HiScore-listan toteutus

Oletko tehnyt jotain, mistä muut voisivat hyötyä. Postita vinkit tänne.
Post Reply
User avatar
valscion
Moderator
Moderator
Posts: 1599
Joined: Thu Dec 06, 2007 7:46 pm
Location: Espoo
Contact:

HiScore-listan toteutus

Post by valscion »

http://cbkk.systec.fi/koodi.php?id=242

Tarpeellisten ominaisuuksien kantava ennätyslistan toteutusjärjestelmä. Tämä tapa käyttää yhtä merkkijonotaulukkoa, johon tallennetaan kolme tietoa per ennätys: nimi, pisteet ja MD5-hash.

Aja esimerkki pari kertaa niin huomaat, miten ennätykset tallentuvat. (siis jos otat kommentin pois riviltä 28)
Tarvitset MD5-funktion ajaaksesi koodin: http://cbkk.systec.fi/koodi.php?id=102 (jätin sen pois jottei koodi menisi turhan sekavaksi)

Koodi pitäisi olla hyvin kommentoitu, mutta jos et ymmärtänyt jotain kohtaa niin kysy pois =)

Code: Select all

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// TARVITTAVA OSA
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

Include "MD5.cb" // MD5-hash merkkijonosta by Bagard (http://cbkk.systec.fi/koodi.php?id=102)

Const HISCORES_PASSPHRASE = "H#s&_;?€{vH"  // Hashausta varten tarvittava merkkijono
Const HISCORES_FILE       = "hiscores.dat" // Ennätysten tiedosto
Const HISCORES_AMOUNT     = 30             // Ennätysten määrä
Const HISCORES_MAXLENGTH  = 20             // Nimen maksimipituus

Dim HISCORES(HISCORES_AMOUNT, 3) As String
// (x, 0) = nimi
// (x, 1) = pisteet
// (x, 2) = hash

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// TARVITTAVA OSA
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// ESIMERKKIOHJELMA
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

    SCREEN 500, 500

    // Ota alla olevan rivin kommentointi pois nähdäksesi miten tallennus sujuu
    'LoadHiScores("Nimetön") // Ladataan ennätykset, tyhjät ennätykset asetetaan nimelle Nimetön

    For i=1 To HISCORES_AMOUNT
        // Asetetaan maksimimäärä nimiä ennätyslistaan
        SetHiScore( "Heppu-"+i, Rand(10000) )
    Next i

    SaveHiScores() // Tallennetaan lista HISCORES_FILE tiedostoon

    Color cbBlue // Ohjetekstien väri

    SetWindow "esim. 1"
    Repeat
        Text 0, 0, "Paina ENTER tai SPACE siirtyäksesi seuraavaan esimerkkiin"

        Text 0, 470, "Tulostetaan lista loopissa, käytetään oletusarvoja."
        Text 0, 483, "x-koord: 20, y-koord: 40"
        PrintHiScores( 20, 40 )

        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)

    SetWindow "esim. 2"
    Repeat
        Text 0, 0, "Paina ENTER tai SPACE siirtyäksesi viimeiseen esimerkkiin"

        Text 0, 470, "Tulostetaan 10 ensimmäistä ennätystä käyttäen väreinä"
        Text 0, 483, "hopeaa ja magentaa (RGB: 192,192,192 ja 255,0,255)."
        PrintHiScores( 20, 40, 0, 10, 192,192,192, 255,0,255 )

        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)

    currentHS=0 // tarvittava apumuuttuja
    SetWindow "esim. 3"
    Repeat
        Text 0, 0, "Selaa ennätyksiä ylös- ja alas-nuolinäppäimillä."
        Text 0, 13, "ESC/ENTER/SPACE lopettaa esimerkin."

        // Siirrytään 5 nimeä eteen/taaksepäin nuolinäppäimillä
        If KeyHit(cbKeyDown) Then currentHS + 5
        If KeyHit(cbKeyUp) Then currentHS - 5

        // Pidetään muuttujan arvot rajojen sisällä
        If currentHS < 0 Then currentHS = 0
        If currentHS > HISCORES_AMOUNT-10 Then currentHS = HISCORES_AMOUNT-10

        Text 0, 470, "Tulostetaan 10 arvoa lähtien muuttujan currentHS kohdasta."
        Text 0, 483, "Väreinä cbLightBlue ja cbPink, x-koord: 20, y-koord:40"
        PrintHiScores( 20, 40, currentHS, 10, cbLightBlue, cbPink )

        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)
    End

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ESIMERKKIOHJELMA
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//==================================================================
// FUNKTIOT
//==================================================================

//------------------------------------------------------------------
// Viimeiseen (ylimääräiseen) soluun lisätään uusi tulos
// ja sitten järjestetään taulukko.
//------------------------------------------------------------------

Function SetHiScore(_nickname$, _score)
    If Len(_nickname$) > HISCORES_MAXLENGTH Then
        // Rajoitetaan nimen pituus
        _nickname$ = Left( _nickname$, HISCORES_MAXLENGTH )
    EndIf
    hash$ = MD5(_nickname + _score + HISCORES_PASSPHRASE)
    HISCORES( HISCORES_AMOUNT, 0 ) = _nickname
    HISCORES( HISCORES_AMOUNT, 1 ) = Str(_score)
    HISCORES( HISCORES_AMOUNT, 2 ) = hash

    SortHiScores()

    // Asetetaan viimeinen paikka tyhjäksi
    HISCORES( HISCORES_AMOUNT, 0 ) = ""
    HISCORES( HISCORES_AMOUNT, 1 ) = ""
    HISCORES( HISCORES_AMOUNT, 2 ) = ""
EndFunction

//------------------------------------------------------------------
// Tallentaa hiscoret tiedostoon. Huomaa, että viimeinen solu,
// joka on varattu uusille ennätyksille, ei tule tiedostoon mukaan.
//------------------------------------------------------------------

Function SaveHiScores()
    If FileExists(HISCORES_FILE) Then DeleteFile HISCORES_FILE
    f = OpenToWrite(HISCORES_FILE)
        For i=0 To HISCORES_AMOUNT-1
            WriteString f, HISCORES(i, 0)
            WriteString f, HISCORES(i, 1)
            WriteString f, HISCORES(i, 2)
        Next i
    CloseFile f
EndFunction

//------------------------------------------------------------------
// Lataa hiscore-taulukon HISCORES_FILE tiedostosta. Jos tiedosto
// on korruptoitunut (esim. joku on muuttanut tekstieditorilla
// pisteitänsä käsin) niin heitetään MakeErrorilla virhe muotoa:
//    Korruptoitunut ennätystiedosto! (ennätystiedosto.dat)
//    Poista se päästäksesi eroon tästä viestistä.
//------------------------------------------------------------------

Function LoadHiScores(_defname$ = "Nobody")
    If Not FileExists(HISCORES_FILE) Or IsDirectory(HISCORES_FILE) Then
        For i=0 To HISCORES_AMOUNT-1
            HISCORES(i, 0) = _defname$
            HISCORES(i, 1) = "0"
            HISCORES(i, 2) = MD5( _defname$ + "0" + HISCORES_PASSPHRASE )
        Next i
        Return False
    EndIf

    f = OpenToRead(HISCORES_FILE)
        For i=0 To HISCORES_AMOUNT-1
            If Not EOF(f) Then
                name$  = ReadString(f)
                If EOF(f) Then MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."
                score$ = ReadString(f)
                If EOF(f) Then MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."
                hash$  = ReadString(f)
                check$ = MD5(name + score + HISCORES_PASSPHRASE)
                If( hash$ <> MD5(name + score + HISCORES_PASSPHRASE) ) Then
                    MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."+Chr(10)+Chr(13)+Chr(10)+Chr(13)+hash$+Chr(10)+Chr(13)+check$
                EndIf

                HISCORES(i, 0) = name
                HISCORES(i, 1) = score
                HISCORES(i, 2) = hash
            Else
                HISCORES(i, 0) = _defname$
                HISCORES(i, 1) = "0"
                HISCORES(i, 2) = MD5( _defname$ + "0" + HISCORES_PASSPHRASE )
            EndIf
        Next i
    CloseFile f

    SortHiScores()

    Return True
EndFunction

//------------------------------------------------------------------
// Tulostaa hiscore-listan näytölle. Funktio säilyttää nykyisen
// piirtovärin. Parametrit:
//      _X: vasemman laidan x-koordinaatti tekstille
//      _Y: ensimmäisen rivin y-koordinaatti
//  _from: monennesta ennätyksestä aletaan tulostamaan tekstiä
//          (oletuksena alusta)
// _amount: kuinka monta ennätystä tulostetaan (ol. loppuun asti)
// _r-g-b1: Ensimmäinen väri (oletuksena cbWhite; 255,255,255)
// _r-g-b2: Toinen väri (oletuksena cbGreen; 128,168,4)
//------------------------------------------------------------------

Function PrintHiScores( _X, _Y, _from=0, _amount=-1, _r1=255, _g1=255, _b1=255, _r2=128, _g2=168, _b2=4 )
    oldr=getRGB(RED):oldg=getRGB(GREEN):oldb=getRGB(BLUE)
    height = TextHeight("I")
    If _from < 0 Then _from=0 : ElseIf _from > HISCORES_AMOUNT-1 Then _from = HISCORES_AMOUNT-1
    If _amount = -1 Or (_from+_amount)>(HISCORES_AMOUNT) Then _amount = HISCORES_AMOUNT
    j=0
    x2 = _X + TextWidth("99. ")
    x3 = x2 + TextWidth( String("#", HISCORES_MAXLENGTH) )
    For i=_from To _from+_amount-1
        j=j+1
        If(j Mod 2) Then Color _r1,_g1,_b1 Else Color _r2,_g2,_b2

        Text _X, _Y + height*j, (i+1)+"."
        Text x2, _Y + height*j, HISCORES(i, 0)
        Text x3, _Y + height*j, HISCORES(i, 1)
    Next i
    Color oldr, oldg, oldb
EndFunction

//------------------------------------------------------------------
// Järjestää hiscore-listan suurimmasta pienimpään
// bubblesort-nimisellä algoritmilla.
//------------------------------------------------------------------

Function SortHiScores()
    For i = 0 To HISCORES_AMOUNT Step 1
        For o = i-1 To 0 Step -1
            If Int(HISCORES(o, 1)) < Int(HISCORES(o+1, 1))
                For lokero=0 To 2
                    temp$ = HISCORES(o, lokero)
                    HISCORES(o, lokero) = HISCORES(o+1, lokero)
                    HISCORES(o+1, lokero) = temp
                Next lokero
            EndIf
        Next o
    Next i
EndFunction 
P.S.
Voit vaihdella siinä alussa olevian vakioiden arvoja ja sitten katsella, miten esimerkki vaihtaa käyttäytymistään.
EDIT:

Koko koodi suoraan ajettavaksi (md5-funktion kanssa siis):

Code: Select all

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// TARVITTAVA OSA
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

Const HISCORES_PASSPHRASE = "H#s&_;?€{vH"  // Hashausta varten tarvittava merkkijono
Const HISCORES_FILE       = "hiscores.dat" // Ennätysten tiedosto
Const HISCORES_AMOUNT     = 30             // Ennätysten määrä
Const HISCORES_MAXLENGTH  = 20             // Nimen maksimipituus

Dim HISCORES(HISCORES_AMOUNT, 3) As String
// (x, 0) = nimi
// (x, 1) = pisteet
// (x, 2) = hash

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// TARVITTAVA OSA
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// ESIMERKKIOHJELMA
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

    SCREEN 500, 500
    
    // Ota alla olevan rivin kommentointi pois nähdäksesi miten tallennus sujuu
    'LoadHiScores("Nimetön") // Ladataan ennätykset, tyhjät ennätykset asetetaan nimelle Nimetön
    
    For i=1 To HISCORES_AMOUNT
        // Asetetaan maksimimäärä nimiä ennätyslistaan
        SetHiScore( "Heppu-"+i, Rand(10000) )
    Next i
    
    SaveHiScores() // Tallennetaan lista HISCORES_FILE tiedostoon
    
    Color cbBlue // Ohjetekstien väri
    
    SetWindow "esim. 1"
    Repeat
        Text 0, 0, "Paina ENTER tai SPACE siirtyäksesi seuraavaan esimerkkiin"
    
        Text 0, 470, "Tulostetaan lista loopissa, käytetään oletusarvoja."
        Text 0, 483, "x-koord: 20, y-koord: 40"
        PrintHiScores( 20, 40 )
        
        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)
    
    SetWindow "esim. 2"
    Repeat
        Text 0, 0, "Paina ENTER tai SPACE siirtyäksesi viimeiseen esimerkkiin"
        
        Text 0, 470, "Tulostetaan 10 ensimmäistä ennätystä käyttäen väreinä"
        Text 0, 483, "hopeaa ja magentaa (RGB: 192,192,192 ja 255,0,255)."
        PrintHiScores( 20, 40, 0, 10, 192,192,192, 255,0,255 )
        
        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)
    
    currentHS=0 // tarvittava apumuuttuja
    SetWindow "esim. 3"
    Repeat
        Text 0, 0, "Selaa ennätyksiä ylös- ja alas-nuolinäppäimillä."
        Text 0, 13, "ESC/ENTER/SPACE lopettaa esimerkin."
        
        // Siirrytään 5 nimeä eteen/taaksepäin nuolinäppäimillä
        If KeyHit(cbKeyDown) Then currentHS + 5
        If KeyHit(cbKeyUp) Then currentHS - 5
        
        // Pidetään muuttujan arvot rajojen sisällä
        If currentHS < 0 Then currentHS = 0
        If currentHS > HISCORES_AMOUNT-10 Then currentHS = HISCORES_AMOUNT-10
        
        Text 0, 470, "Tulostetaan 10 arvoa lähtien muuttujan currentHS kohdasta."
        Text 0, 483, "Väreinä cbLightBlue ja cbPink, x-koord: 20, y-koord:40"
        PrintHiScores( 20, 40, currentHS, 10, cbLightBlue, cbPink )
        
        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)
    End

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ESIMERKKIOHJELMA
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//==================================================================
// FUNKTIOT
//==================================================================

//------------------------------------------------------------------
// Viimeiseen (ylimääräiseen) soluun lisätään uusi tulos
// ja sitten järjestetään taulukko.
//------------------------------------------------------------------

Function SetHiScore(_nickname$, _score)
    If Len(_nickname$) > HISCORES_MAXLENGTH Then 
        // Rajoitetaan nimen pituus
        _nickname$ = Left( _nickname$, HISCORES_MAXLENGTH )
    EndIf
    hash$ = MD5(_nickname + _score + HISCORES_PASSPHRASE)
    HISCORES( HISCORES_AMOUNT, 0 ) = _nickname
    HISCORES( HISCORES_AMOUNT, 1 ) = Str(_score)
    HISCORES( HISCORES_AMOUNT, 2 ) = hash

    SortHiScores()
    
    // Asetetaan viimeinen paikka tyhjäksi
    HISCORES( HISCORES_AMOUNT, 0 ) = ""
    HISCORES( HISCORES_AMOUNT, 1 ) = ""
    HISCORES( HISCORES_AMOUNT, 2 ) = ""
EndFunction

//------------------------------------------------------------------
// Tallentaa hiscoret tiedostoon. Huomaa, että viimeinen solu,
// joka on varattu uusille ennätyksille, ei tule tiedostoon mukaan.
//------------------------------------------------------------------

Function SaveHiScores()
    If FileExists(HISCORES_FILE) Then DeleteFile HISCORES_FILE
    f = OpenToWrite(HISCORES_FILE)
        For i=0 To HISCORES_AMOUNT-1
            WriteString f, HISCORES(i, 0)
            WriteString f, HISCORES(i, 1)
            WriteString f, HISCORES(i, 2)
        Next i
    CloseFile f
EndFunction

//------------------------------------------------------------------
// Lataa hiscore-taulukon HISCORES_FILE tiedostosta. Jos tiedosto
// on korruptoitunut (esim. joku on muuttanut tekstieditorilla
// pisteitänsä käsin) niin heitetään MakeErrorilla virhe muotoa:
//    Korruptoitunut ennätystiedosto! (ennätystiedosto.dat)
//    Poista se päästäksesi eroon tästä viestistä.
//------------------------------------------------------------------

Function LoadHiScores(_defname$ = "Nobody")
    If Not FileExists(HISCORES_FILE) Or IsDirectory(HISCORES_FILE) Then
        For i=0 To HISCORES_AMOUNT-1
            HISCORES(i, 0) = _defname$
            HISCORES(i, 1) = "0"
            HISCORES(i, 2) = MD5( _defname$ + "0" + HISCORES_PASSPHRASE )
        Next i
        Return False
    EndIf
    
    f = OpenToRead(HISCORES_FILE)
        For i=0 To HISCORES_AMOUNT-1
            If Not EOF(f) Then
                name$  = ReadString(f)
                If EOF(f) Then MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."
                score$ = ReadString(f)
                If EOF(f) Then MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."
                hash$  = ReadString(f)
                check$ = MD5(name + score + HISCORES_PASSPHRASE)
                If( hash$ <> MD5(name + score + HISCORES_PASSPHRASE) ) Then
                    MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."+Chr(10)+Chr(13)+Chr(10)+Chr(13)+hash$+Chr(10)+Chr(13)+check$
                EndIf
                
                HISCORES(i, 0) = name
                HISCORES(i, 1) = score
                HISCORES(i, 2) = hash
            Else
                HISCORES(i, 0) = _defname$
                HISCORES(i, 1) = "0"
                HISCORES(i, 2) = MD5( _defname$ + "0" + HISCORES_PASSPHRASE )
            EndIf
        Next i
    CloseFile f
    
    SortHiScores()
    
    Return True
EndFunction

//------------------------------------------------------------------
// Tulostaa hiscore-listan näytölle. Funktio säilyttää nykyisen
// piirtovärin. Parametrit:
//      _X: vasemman laidan x-koordinaatti tekstille
//      _Y: ensimmäisen rivin y-koordinaatti
//   _from: monennesta ennätyksestä aletaan tulostamaan tekstiä
//          (oletuksena alusta)
// _amount: kuinka monta ennätystä tulostetaan (ol. loppuun asti)
// _r-g-b1: Ensimmäinen väri (oletuksena cbWhite; 255,255,255)
// _r-g-b2: Toinen väri (oletuksena cbGreen; 128,168,4)
//------------------------------------------------------------------

Function PrintHiScores( _X, _Y, _from=0, _amount=-1, _r1=255, _g1=255, _b1=255, _r2=128, _g2=168, _b2=4 )
    oldr=getRGB(RED):oldg=getRGB(GREEN):oldb=getRGB(BLUE)
    height = TextHeight("I")
    If _from < 0 Then _from=0 : ElseIf _from > HISCORES_AMOUNT-1 Then _from = HISCORES_AMOUNT-1
    If _amount = -1 Or (_from+_amount)>(HISCORES_AMOUNT) Then _amount = HISCORES_AMOUNT
    j=0
    x2 = _X + TextWidth("99. ")
    x3 = x2 + TextWidth( String("#", HISCORES_MAXLENGTH) )
    For i=_from To _from+_amount-1
        j=j+1
        If(j Mod 2) Then Color _r1,_g1,_b1 Else Color _r2,_g2,_b2
        
        Text _X, _Y + height*j, (i+1)+"."
        Text x2, _Y + height*j, HISCORES(i, 0)
        Text x3, _Y + height*j, HISCORES(i, 1)
    Next i
    Color oldr, oldg, oldb
EndFunction

//------------------------------------------------------------------
// Järjestää hiscore-listan suurimmasta pienimpään 
// bubblesort-nimisellä algoritmilla.
//------------------------------------------------------------------

Function SortHiScores()
    For i = 0 To HISCORES_AMOUNT Step 1
        For o = i-1 To 0 Step -1
            If Int(HISCORES(o, 1)) < Int(HISCORES(o+1, 1))
                For lokero=0 To 2
                    temp$ = HISCORES(o, lokero)
                    HISCORES(o, lokero) = HISCORES(o+1, lokero)
                    HISCORES(o+1, lokero) = temp
                Next lokero
            EndIf
        Next o
    Next i
EndFunction 

Function MD5(jono$)

    nblk = ((Len(jono$) + 8) Shr 6) + 1

    Dim MD5_x(nblk * 16 - 1)

    For i = 0 To nblk * 16 - 1
        MD5_x(i) = 0
    Next i

    For i = 0 To (Len(jono$) - 1)
        MD5_x(i Shr 2) = BinOr(MD5_x(i Shr 2), (Asc(Mid(jono$, (i + 1), 1)) Shl ((i Mod 4) * 8)))
    Next i

    MD5_x(i Shr 2) = BinOr(MD5_x(i Shr 2), (128 Shl (((i) Mod 4) * 8)))
    MD5_x(nblk * 16 - 2) = Len(jono$) * 8

    MD5_a = 1732584193 //&H67452301
    MD5_b = -271733879 //&HEFCDAB89
    MD5_c = -1732584194 //&H98BADCFE
    MD5_d = 271733878 //&H10325476

    // Käydään sanat läpi
    For k = 0 To (nblk * 16 - 1) Step 16
        MD5_AA = MD5_a
        MD5_BB = MD5_b
        MD5_CC = MD5_c
        MD5_DD = MD5_d

        // Kierros 1
        MD5_a = MD5_FF(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 0), 7, -680876936) //&HD76AA478
        MD5_d = MD5_FF(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 1), 12, -389564586) //&HE8C7B756
        MD5_c = MD5_FF(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 2), 17, 606105819 )//&H242070DB
        MD5_b = MD5_FF(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 3), 22, -1044525330) //&HC1BDCEEE
        MD5_a = MD5_FF(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 4), 7, -176418897) //&HF57C0FAF
        MD5_d = MD5_FF(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 5), 12, 1200080426 )//&H4787C62A
        MD5_c = MD5_FF(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 6), 17, -1473231341) //&HA8304613
        MD5_b = MD5_FF(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 7), 22, -45705983) //&HFD469501
        MD5_a = MD5_FF(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 8), 7, 1770035416) //&H698098D8
        MD5_d = MD5_FF(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 9), 12, -1958414417 )//&H8B44F7AF
        MD5_c = MD5_FF(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 10), 17, -42063 )//&HFFFF5BB1
        MD5_b = MD5_FF(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 11), 22, -1990404162) //&H895CD7BE
        MD5_a = MD5_FF(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 12), 7, 1804603682) //&H6B901122
        MD5_d = MD5_FF(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 13), 12, -40341101) //&HFD987193
        MD5_c = MD5_FF(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 14), 17, -1502002290) //&HA679438E
        MD5_b = MD5_FF(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 15), 22, 1236535329) //&H49B40821

        // Kierros 2
        MD5_a = MD5_GG(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 1), 5, -165796510) //&HF61E2562
        MD5_d = MD5_GG(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 6), 9, -1069501632) //&HC040B340
        MD5_c = MD5_GG(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 11), 14, 643717713) //&H265E5A51
        MD5_b = MD5_GG(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 0), 20, -373897302) //&HE9B6C7AA
        MD5_a = MD5_GG(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 5), 5, -701558691) //&HD62F105D
        MD5_d = MD5_GG(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 10), 9, 38016083) //&H2441453
        MD5_c = MD5_GG(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 15), 14, -660478335) //&HD8A1E681
        MD5_b = MD5_GG(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 4), 20, -405537848) //&HE7D3FBC8
        MD5_a = MD5_GG(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 9), 5, 568446438) //&H21E1CDE6
        MD5_d = MD5_GG(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 14), 9, -1019803690) //&HC33707D6
        MD5_c = MD5_GG(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 3), 14, -187363961) //&HF4D50D87
        MD5_b = MD5_GG(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 8), 20, 1163531501) //&H455A14ED
        MD5_a = MD5_GG(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 13), 5, -1444681467) //&HA9E3E905
        MD5_d = MD5_GG(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 2), 9, -51403784) //&HFCEFA3F8
        MD5_c = MD5_GG(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 7), 14, 1735328473) //&H676F02D9
        MD5_b = MD5_GG(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 12), 20, -1926607734) //&H8D2A4C8A

        // Kierros 3
        MD5_a =  MD5_HH(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 5), 4, -378558) //&HFFFA3942
        MD5_d =  MD5_HH(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 8), 11, -2022574463) //&H8771F681
        MD5_c = MD5_HH(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 11), 16, 1839030562) //&H6D9D6122
        MD5_b = MD5_HH(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 14), 23, -35309556) //&HFDE5380C
        MD5_a =  MD5_HH(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 1), 4, -1530992060) //&HA4BEEA44
        MD5_d = MD5_HH(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 4), 11, 1272893353) //&H4BDECFA9
        MD5_c = MD5_HH(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 7), 16, -155497632) //&HF6BB4B60
        MD5_b = MD5_HH(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 10), 23, -1094730640) //&HBEBFBC70
        MD5_a = MD5_HH(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 13), 4, 681279174) //&H289B7EC6
        MD5_d = MD5_HH(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 0), 11, -358537222) //&HEAA127FA
        MD5_c = MD5_HH(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 3), 16, -722521979) //&HD4EF3085
        MD5_b = MD5_HH(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 6), 23, 76029189) //&H4881D05
        MD5_a = MD5_HH(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 9), 4, -640364487) //&HD9D4D039
        MD5_d = MD5_HH(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 12), 11, -421815835) //&HE6DB99E5
        MD5_c = MD5_HH(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 15), 16, 530742520) //&H1FA27CF8
        MD5_b = MD5_HH(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 2), 23, -995338651) //&HC4AC5665

        // Kierros 4
        MD5_a = MD5_II(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 0), 6, -198630844) //&HF4292244
        MD5_d = MD5_II(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 7), 10, 1126891415) //&H432AFF97
        MD5_c = MD5_II(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 14), 15, -1416354905) //&HAB9423A7
        MD5_b = MD5_II(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 5), 21, -57434055) //&HFC93A039
        MD5_a = MD5_II(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 12), 6, 1700485571) //&H655B59C3
        MD5_d = MD5_II(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 3), 10, -1894986606) //&H8F0CCC92
        MD5_c = MD5_II(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 10), 15, -1051523) //&HFFEFF47D
        MD5_b = MD5_II(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 1), 21, -2054922799) //&H85845DD1
        MD5_a = MD5_II(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 8), 6, 1873313359) //&H6FA87E4F
        MD5_d = MD5_II(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 15), 10, -30611744) //&HFE2CE6E0
        MD5_c = MD5_II(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 6), 15, -1560198380 )//&HA3014314
        MD5_b = MD5_II(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 13), 21, 1309151649) //&H4E0811A1
        MD5_a = MD5_II(MD5_a, MD5_b, MD5_c, MD5_d, MD5_x(k + 4), 6, -145523070) //&HF7537E82
        MD5_d = MD5_II(MD5_d, MD5_a, MD5_b, MD5_c, MD5_x(k + 11), 10, -1120210379) //&HBD3AF235
        MD5_c = MD5_II(MD5_c, MD5_d, MD5_a, MD5_b, MD5_x(k + 2), 15, 718787259) //&H2AD7D2BB
        MD5_b = MD5_II(MD5_b, MD5_c, MD5_d, MD5_a, MD5_x(k + 9), 21, -343485551) //&HEB86D391

        MD5_a = MD5_a + MD5_AA
        MD5_b = MD5_b + MD5_BB
        MD5_c = MD5_c + MD5_CC
        MD5_d = MD5_d + MD5_DD
    Next k

    Return Lower(Str(WordToHex(MD5_a)) + Str(WordToHex(MD5_b)) + Str(WordToHex(MD5_c)) + Str(WordToHex(MD5_d)))
End Function


Function MD5_F(x, y, z)
    Return BinOr(BinAnd(x, y), BinAnd(BinNot(x), z))
End Function

Function MD5_G(x, y, z)
    Return BinOr(BinAnd(x, z), BinAnd(y, BinNot(z)))
End Function

Function MD5_H(x, y, z)
    Return BinXor(BinXor(x, y), z)
End Function

Function MD5_I(x, y, z)
    Return BinXor(y, BinOr(x, BinNot(z)))
End Function

Function MD5_FF(a, b, c, d, x, s, ac)
    a = (a + ((MD5_F(b, c, d)+ x)+ ac))
    a = RotateLeft(a, s)
    Return a + b
End Function

Function MD5_GG(a, b, c, d, x, s, ac)
    a = (a + ((MD5_G(b, c, d) + x) + ac))
    a = RotateLeft(a, s)
    Return a + b
End Function

Function MD5_HH(a, b, c, d, x, s, ac)
    a = (a + ((MD5_H(b, c, d) + x) + ac))
    a = RotateLeft(a, s)
    Return a + b
End Function

Function MD5_II(a, b, c, d, x, s, ac)
    a = (a + ((MD5_I(b, c, d) + x) + ac))
    a = RotateLeft(a, s)
    Return a + b
End Function

Function RotateLeft(lValue, iShiftBits)
    Return BinOr(lValue Shl iShiftBits, lValue Shr (32 - iShiftBits))
End Function

Function WordToHex(lValue)
    For lCount = 0 To 3
        lByte = BinAnd(lValue Shr lCount * 8, 255)
        ToHex$ = ToHex$ + Right("0" + Hex(lByte), 2)
    Next lCount
    Return ToHex$
End Function

Function BinAnd(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) And ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinNot(luku1)
    For i = 0 To 31
        luku3 = luku3 + (Not ((luku1 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinXor(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) Xor ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinOr(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) Or ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function Bin2Dec(jono$)
    For i = Len(jono$) To 1 Step -1
        arvo = Int(Mid(jono$, i, 1))
        If arvo = 1 Then
            luku = luku + 2 ^ (Len(jono$) - i)
        EndIf
    Next i
    Return luku
End Function 
[/edit]
cbEnchanted, uudelleenkirjoitettu runtime. Uusin versio: 0.4.1 — Nyt myös sorsat GitHubissa!
NetMatch - se kunnon nettimättö-deathmatch! Avoimella lähdekoodilla varustettu
vesalaakso.com
Post Reply