Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: [VB6] Stringin kasvatus hidastuu (VB.NET)

Sivun loppuun

JussiR [23.03.2010 09:27:09]

#

Hei,

Onko parempaa tapaa muuntaa teksti "VB-koodiksi" kuin alla oleva koodini tekee? Eli esim "moi" olisi "Chr(109) & Chr(111) & Chr(105)"

Jos teksti on pitkä, huomaa kuinka ohjelma hidastuu sitä mukaa kun se etenee. Ja se johtuu tuosta kohdasta jossa returnTxt:ksi asetetaan muunnetun tekstin lisäksi oma itsenä koko ajan uudelleen ja sehän kasvaa koko ajan.. Olen usein törmännyt vastaavaan ongelmaan.

Pitäisikö tuo muunnos tehdä suuremmissa osissa vai miten ihmeessä?

Private Sub Command1_Click()
Dim returnText As String
On Error GoTo err

Command1.Enabled = False

txtToChr Text1, returnText

Text2 = returnText

GoTo bye

err:
MsgBox "Error: " & Error

bye:
Command1.Enabled = True
End Sub

Sub txtToChr(Txt As String, ByRef returnTxt As String)
On Error GoTo err

Dim n As Long, txtLen As Long
Dim titleBckUp As String
titleBckUp = Me.Caption

'Laitetaan tuo nyt tässä erikseen, ettei tarvitse laskea koko ajan uudelleen tuolla loopissa
txtLen = Len(Txt)

For n = 1 To txtLen
    returnTxt = returnTxt + "Chr(" & Asc(Mid(Txt, n, 1)) & ") & "

    'Näytetään eteneminen ohjelman otsikossa
    Me.Caption = Round(n / txtLen, 2) * 100 & " %"

    'Että ohjelmalla voisi tehdä jotain muutakin samaan aikaan
    DoEvents
Next n

'Ylimääräiset pois -.-
returnTxt = Mid(returnTxt, 1, Len(returnTxt) - 3)

GoTo bye

err:
MsgBox "txtToChr error: " & Error, vbCritical

bye:
Me.Caption = titleBckUp
End Sub

Metabolix [23.03.2010 09:42:57]

#

Koodisi hitaus johtuu luultavasti ensisijaisesti siitä, että joka merkin jälkeen päivität otsikon ja käsittelet tapahtumat. Jos otat nuo kaksi riviä silmukasta pois, pitkäkin teksti luultavasti muuttuu varsin nopeasti.

Jotta koodistasi saisi jotain selvää, kannattaisi sisentää se kunnolla.

JussiR [23.03.2010 09:45:06]

#

Hei,

Otsikkohommeli on väliaikainen, että näen miten se edistyy. DoEvents on pakollinen, että ohjelmalla voisi tehdä jotain muutakin samaan aikaan.

Kyllähän ne hidastaa reilusti, mutta tasainen hitaus ei ole nyt se ongelma vaan hidasTUMINEN koko ajan enemmän, jos teksti on pitkä.
Pitäisikö teksti pilkkoa osiin ja käsitellä ne erikseen ja lopuksi lisätä yhteen?

Metabolix [23.03.2010 09:55:37]

#

DoEventsiä ei missään tapauksessa kannata ajaa joka kierroksella, vaan voit ajaa sen vaikka sadan tai tuhannen merkin välein (sen mukaan, miten nopeasti algoritmi toimii).

Luultavasti &-operaatio aina varaa uuden tekstin ja kopioi aiemmat sinne, ja =-operaatio kopioi lopuksi uuden tekstin vanhan päälle. Algoritmia voisi siis tehostaa varaamalla valmiiksi tarpeeksi pitkän tekstin ja muokkaamalla sitä suoraan (käsittääkseni Mid-lauseella).

Sami [23.03.2010 10:04:47]

#

Olettaisin että VB käsittelee merkkijonoja samaan tapaan kuin Java, eli aina kun lisäät merkkijonon perään jotain, niin se luo joka kerta uuden merkkijonon, joka luonnollisesti hidastaa ohjelmaa merkittävästi jos tätä joudutaan tekemään jatkuvasti.
Hyviä hakusanoja googleen voisi olla esimerkiksi "vb6 string builder" tai "vb6 string buffer".

JussiR [23.03.2010 10:07:47]

#

Midillä (http://msdn.microsoft.com/en-us/library/05e63829(VS.80).aspx) ei taida pystyä muokkaamaan suoraan, mutta katsotaan mitä löydän Samin hakusanoila.

Metabolix [23.03.2010 10:11:26]

#

Kyllä tällä toisella Midillä voi muokata. En tiedä VB6:n tilanteesta, mutta uskoisin, että sama pätee.

Edit: Toteutin ehdotukseni (FreeBASICilla):

' Vanha tapa:
Function A(teksti As String) As String
    Dim koodi As String = ""
    Dim i As Integer
    For i = 1 To Len(teksti)
        koodi = koodi & "Chr(" & Asc(Mid(teksti, i, 1)) & ") & "
    Next
    A = Left(koodi, Len(koodi) - 3)
End Function

' Uusi tapa:
Function B(teksti As String) As String
    Dim koodi As String = Space(Len(teksti) * 11)
    Dim i As Integer
    For i = 1 To Len(teksti)
        Mid(koodi, 1 + 11 * (i - 1)) = "Chr(" & Asc(Mid(teksti, i, 1)) & ") & "
    Next
    B = Left(koodi, InStrRev(koodi, "&") - 2)
End Function

' Testaus
Dim x As String
Dim teksti As String = "abcdefg"
Dim i As Integer
For i = 0 To 11
    teksti = teksti & teksti
Next i

Dim t As Double

t = Timer
x = A(teksti)
Print Timer - t  ' 6,88 sekuntia

t = Timer
x = B(teksti)
Print Timer - t  ' 0,04 sekuntia

JussiR [23.03.2010 10:29:21]

#

Tein Midillä ja tuli aika nopea, mutta mistäköhän johtuu bugi, että tekstin perään tulee eri määrä tuota "ylimääräistä" riippuen siitä mitä Txt sisältää (eli ilmeisesti rplLenin käytössä on jotai pielessä)?

Sub txtToChr(Txt As String, ByRef returnTxt As String)

Dim n As Long, n2 As Long
Dim replaCement As String, rplLen As Integer

    n2 = 1

    returnTxt = Space(Len(Txt) * 11)

    For n = 1 To Len(Txt)
        replaCement = "Chr(" & Asc(Mid(Txt, n, 1)) & ") & "

        rplLen = Len(replaCement)

        Mid(returnTxt, n2, rplLen) = replaCement
        n2 = n2 + rplLen
    Next n

'Ylimääräiset pois -.-
    returnTxt = Mid(returnTxt, 1, Len(returnTxt) - 3)

End Sub

EDIT: Kiitos metabolix, kokeilen tuotakin

Metabolix [23.03.2010 10:43:30]

#

Vika on koodisi lopussa. Tulosta Len(Txt)*11, Len(returnTxt) ja n2, niin näet ongelman.

JussiR [23.03.2010 10:53:39]

#

Juu kiitoksia. Päädyin kuitenkin käyttämään sun funktiota, paitsi ettei ainakaan VBA:ssa ollut Leftiä ollenkaan.

Function txtToChr(Txt As String) As String
    Dim vbCode As String
    vbCode = Space(Len(Txt) * 11)

    Dim i As Integer
    For i = 1 To Len(Txt)
        Mid(vbCode, 1 + 11 * (i - 1)) = "Chr(" & Asc(Mid(Txt, i, 1)) & ") & "
    Next

    txtToChr = Mid(vbCode, 1, InStrRev(vbCode, "&") - 2)
End Function

Tota voi muun muassa käyttää esim. siihen, ettei ihan aloittelija pysty muuttamaan ohjelman sisäisiä tekstejä. Eli pieni anti-crack systeemi.

Esimerkiksi jos halutaan, että ohjelman otsikko on "Program made by Jussi", niin seuraava koodi tarkistaa, ettei sitä ole muutettu esim vbDeFormerilla:

'Seuraava koodi Form_Loadiin:
If Not StrReverse(Me.Caption) = StrReverse(Chr(80) &  Chr(114) & Chr(111) & Chr(103) & Chr(114) & Chr(97) &  Chr(109) & Chr(32) &  Chr(109) & Chr(97) &  Chr(100) & Chr(101) & Chr(32) &  Chr(98) &  Chr(121) & Chr(32) &  Chr(74) &  Chr(117) & Chr(115) & Chr(115) & Chr(105)) Then End

Ja jos tuota tarkistusta haluaa muuttaa, niin kyllä se varmaan vähän päänvaivaa aiheuttaa, kun katsotaan jollain decompilerilla :D

Itse käytän tuota vastaavaan tarkoitukseen.


..Niin tai sitten, jos haluaa edes vähän piilottaa jostain keyloggerista ftp-tunnuksiansa tms. Tosin ne näkee packet snifferillä ja joillain palomuureillakin. Itse laittaisin ohjelman lähettämään tiedot jonkin ilmaisella hostilla olevan php-sivun kautta tietokantaan tai mihin haluaa..
Meni vähän offtopic, mutta kahvi sekotti mun pään. Aika iso pulssi btw.

Metabolix [23.03.2010 14:27:09]

#

Harhautat nyt luultavasti eniten itseäsi. Tuollaisen tarkistuksen voi kiertää ottamalla Not-sanan pois eli vaihtamalla vain hyppykäskyn käänteiseksi, mikä onnistuisi debuggerin ja heksaeditorin avulla parissa minuutissa. Sitä paitsi järkevän kääntäjän pitäisi osata optimoida tuollainen tyhmystely muotoon If Me.Caption <> "...", jolloin muokkaaminen onnistuisi heksaeditorilla ilmankin assemblyn tuntemista. (VB-kääntäjä tosin ei välttämättä ole järkevä.) Jos haluat tarkistaa jotain, laske tarkistussumma (vaikka MD5) tai käytä jotain edes hieman salausalgoritmin tapaista. (Tosin nämäkin voi yleensä kiertää samanlaisella menetelmällä, mutta ainakin koodista tulee kryptisempi.)

JussiR [23.03.2010 20:47:43]

#

Jooh.. Enpä pahemmin ajatellut. Yksi VB encrypter vaan tekee noin, eli sillä ei taida tehdä mitään.

JussiR [29.03.2010 11:58:45]

#

Tämmönen löyty myös.
http://www.xtremevbtalk.com/showthread.php?t­=155206

Metabolix [31.03.2010 10:55:24]

#

Tuohan tekee käytännössä aivan saman asian. Tilaa vain varataan aina tasamäärä megatavuja, kun taas oma koodi osaa laskea paljon tarkemman arvauksen ja on erityisesti pienillä teksteillä kätevämpi. :)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta