Kirjoittaja: kllp
Kirjoitettu: 21.12.2013 – 21.12.2013
Tagit: algoritmit, koodi näytille, vinkki
Tässä md5-algoritmin toteutus QBasicilla.
Joku voisi sanoa jotakin binaarilukujen käsittelemisestä merkkijonoina, mutta näin koodi on mielestäni kuitenkin selkeämpi ja ennen kaikkea tyylikkäämpi. Nopeuskaan ei ole ongelma, koska kieli on niin QUICK (nopea). Niin ja helpompi koodata, jos ei osaa. Paitsi sitten tuli se tavujärjestys hyi olkoon.
Lisää md5-algoritmista voi lukea vaikka seuraavista linkeistä: https://tools.ietf.org/html/rfc1321 ja https://en.wikipedia.org/wiki/MD5
'hyvaan ohjelmointityyliin kuuluu kuvaavat funktioiden nimet :)
DECLARE FUNCTION asctobin$ (a AS STRING)
DECLARE FUNCTION bintohex$ (a AS STRING)
DECLARE FUNCTION hextobin$ (a AS STRING)
'sadd oli kai joku valmis funktio tai joku sellainen QAQ
's siis tulee sanasta "string" :)
DECLARE FUNCTION stadd$ (a AS STRING, b AS STRING)
DECLARE FUNCTION sand$ (a AS STRING, b AS STRING)
DECLARE FUNCTION sor$ (a AS STRING, b AS STRING)
DECLARE FUNCTION snot$ (a AS STRING)
DECLARE FUNCTION sxor$ (a AS STRING, b AS STRING)
DECLARE FUNCTION lrotate$ (a AS STRING, b AS LONG)
'naa on vaan suoraan ne sielta baberista...
DECLARE FUNCTION flol$ (a AS STRING, b AS STRING, c AS STRING)
DECLARE FUNCTION glol$ (a AS STRING, b AS STRING, c AS STRING)
DECLARE FUNCTION ilol$ (a AS STRING, b AS STRING, c AS STRING)
DECLARE FUNCTION hlol$ (a AS STRING, b AS STRING, c AS STRING)
DECLARE FUNCTION r1$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, i AS LONG)
DECLARE FUNCTION r2$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, i AS LONG)
DECLARE FUNCTION r3$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, i AS LONG)
DECLARE FUNCTION r4$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, t AS LONG)
DEFLNG A-Z
DIM a AS STRING
DIM b AS STRING
DIM c AS STRING
DIM d AS STRING
DIM aa AS STRING
DIM bb AS STRING
DIM cc AS STRING
DIM dd AS STRING
DIM SHARED x(16) AS STRING
DIM SHARED t(64) AS STRING 'sinifunktiollakin voisi laskea. minua tosin huoletti vahan ohjelman suorituskyky ja tein nain
DIM syote AS STRING
'jotain maagisia lukuja ei hajuakaan. jannaa :oooo
a = hextobin("67452301")
b = hextobin("efcdab89")
c = hextobin("98badcfe")
d = hextobin("10325476")
FOR i = 0 TO 16
x(i) = hextobin("00000000")
NEXT
t(1) = hextobin("d76aa478")
t(2) = hextobin("e8c7b756")
t(3) = hextobin("242070db")
t(4) = hextobin("c1bdceee")
t(5) = hextobin("f57c0faf")
t(6) = hextobin("4787c62a")
t(7) = hextobin("a8304613")
t(8) = hextobin("fd469501")
t(9) = hextobin("698098d8")
t(10) = hextobin("8b44f7af")
t(11) = hextobin("ffff5bb1")
t(12) = hextobin("895cd7be")
t(13) = hextobin("6b901122")
t(14) = hextobin("fd987193")
t(15) = hextobin("a679438e")
t(16) = hextobin("49b40821")
t(17) = hextobin("f61e2562")
t(18) = hextobin("c040b340")
t(19) = hextobin("265e5a51")
t(20) = hextobin("e9b6c7aa")
t(21) = hextobin("d62f105d")
t(22) = hextobin("02441453")
t(23) = hextobin("d8a1e681")
t(24) = hextobin("e7d3fbc8")
t(25) = hextobin("21e1cde6")
t(26) = hextobin("c33707d6")
t(27) = hextobin("f4d50d87")
t(28) = hextobin("455a14ed")
t(29) = hextobin("a9e3e905")
t(30) = hextobin("fcefa3f8")
t(31) = hextobin("676f02d9")
t(32) = hextobin("8d2a4c8a")
t(33) = hextobin("fffa3942")
t(34) = hextobin("8771f681")
t(35) = hextobin("6d9d6122")
t(36) = hextobin("fde5380c")
t(37) = hextobin("a4beea44")
t(38) = hextobin("4bdecfa9")
t(39) = hextobin("f6bb4b60")
t(40) = hextobin("bebfbc70")
t(41) = hextobin("289b7ec6")
t(42) = hextobin("eaa127fa")
t(43) = hextobin("d4ef3085")
t(44) = hextobin("04881d05")
t(45) = hextobin("d9d4d039")
t(46) = hextobin("e6db99e5")
t(47) = hextobin("1fa27cf8")
t(48) = hextobin("c4ac5665")
t(49) = hextobin("f4292244")
t(50) = hextobin("432aff97")
t(51) = hextobin("ab9423a7")
t(52) = hextobin("fc93a039")
t(53) = hextobin("655b59c3")
t(54) = hextobin("8f0ccc92")
t(55) = hextobin("ffeff47d")
t(56) = hextobin("85845dd1")
t(57) = hextobin("6fa87e4f")
t(58) = hextobin("fe2ce6e0")
t(59) = hextobin("a3014314")
t(60) = hextobin("4e0811a1")
t(61) = hextobin("f7537e82")
t(62) = hextobin("bd3af235")
t(63) = hextobin("2ad7d2bb")
t(64) = hextobin("eb86d391")
CLS
INPUT "Anna syote: ", syote
'p tulee sanasta "pituus" ja a sanasta "aluksi". Loogista, eiko totta!
pa = LEN(syote)
'lisataan loppuun ykkosbitti
syote = syote + CHR$(&H80)
WHILE LEN(syote) MOD 64 <> 56 'elikkas siis pitaa olla kongruentti 488 (mod 512)
syote = syote + CHR$(0)
WEND
'syotteen alkuperainen pituus bitteina lisataan syotteen loppuun
pa = pa * 8
WHILE pa
syote = syote + CHR$(pa MOD 256) 'kaantyy sitten myohemmin toisin pain bittijarjestyksen muuttuessa
pa = pa \ 256
WEND
'taytetaan nollilla loppu
WHILE LEN(syote) MOD 64 <> 0
syote = syote + CHR$(0)
WEND
'kasitellaan 512 bitin osissa
'vinkki: taman voi toteuttaa myos funktiona (hyva kotitehtava!)
FOR i = 0 TO LEN(syote) - 1 STEP 64
aa = a
bb = b
cc = c
dd = d
'little endian vahan monimutkaistaa
FOR j = 0 TO 64
MID$(x(j \ 4), ((3 - (j MOD 4)) * 8) + 1) = asctobin(MID$(syote, (j + i) + 1, 1))
NEXT
a = r1(a, b, c, d, 0, 7, 1)
d = r1(d, a, b, c, 1, 12, 2)
c = r1(c, d, a, b, 2, 17, 3)
b = r1(b, c, d, a, 3, 22, 4)
a = r1(a, b, c, d, 4, 7, 5)
d = r1(d, a, b, c, 5, 12, 6)
c = r1(c, d, a, b, 6, 17, 7)
b = r1(b, c, d, a, 7, 22, 8)
a = r1(a, b, c, d, 8, 7, 9)
d = r1(d, a, b, c, 9, 12, 10)
c = r1(c, d, a, b, 10, 17, 11)
b = r1(b, c, d, a, 11, 22, 12)
a = r1(a, b, c, d, 12, 7, 13)
d = r1(d, a, b, c, 13, 12, 14)
c = r1(c, d, a, b, 14, 17, 15)
b = r1(b, c, d, a, 15, 22, 16)
a = r2(a, b, c, d, 1, 5, 17)
d = r2(d, a, b, c, 6, 9, 18)
c = r2(c, d, a, b, 11, 14, 19)
b = r2(b, c, d, a, 0, 20, 20)
a = r2(a, b, c, d, 5, 5, 21)
d = r2(d, a, b, c, 10, 9, 22)
c = r2(c, d, a, b, 15, 14, 23)
b = r2(b, c, d, a, 4, 20, 24)
a = r2(a, b, c, d, 9, 5, 25)
d = r2(d, a, b, c, 14, 9, 26)
c = r2(c, d, a, b, 3, 14, 27)
b = r2(b, c, d, a, 8, 20, 28)
a = r2(a, b, c, d, 13, 5, 29)
d = r2(d, a, b, c, 2, 9, 30)
c = r2(c, d, a, b, 7, 14, 31)
b = r2(b, c, d, a, 12, 20, 32)
a = r3(a, b, c, d, 5, 4, 33)
d = r3(d, a, b, c, 8, 11, 34)
c = r3(c, d, a, b, 11, 16, 35)
b = r3(b, c, d, a, 14, 23, 36)
a = r3(a, b, c, d, 1, 4, 37)
d = r3(d, a, b, c, 4, 11, 38)
c = r3(c, d, a, b, 7, 16, 39)
b = r3(b, c, d, a, 10, 23, 40)
a = r3(a, b, c, d, 13, 4, 41)
d = r3(d, a, b, c, 0, 11, 42)
c = r3(c, d, a, b, 3, 16, 43)
b = r3(b, c, d, a, 6, 23, 44)
a = r3(a, b, c, d, 9, 4, 45)
d = r3(d, a, b, c, 12, 11, 46)
c = r3(c, d, a, b, 15, 16, 47)
b = r3(b, c, d, a, 2, 23, 48)
a = r4(a, b, c, d, 0, 6, 49)
d = r4(d, a, b, c, 7, 10, 50)
c = r4(c, d, a, b, 14, 15, 51)
b = r4(b, c, d, a, 5, 21, 52)
a = r4(a, b, c, d, 12, 6, 53)
d = r4(d, a, b, c, 3, 10, 54)
c = r4(c, d, a, b, 10, 15, 55)
b = r4(b, c, d, a, 1, 21, 56)
a = r4(a, b, c, d, 8, 6, 57)
d = r4(d, a, b, c, 15, 10, 58)
c = r4(c, d, a, b, 6, 15, 59)
b = r4(b, c, d, a, 13, 21, 60)
a = r4(a, b, c, d, 4, 6, 61)
d = r4(d, a, b, c, 11, 10, 62)
c = r4(c, d, a, b, 2, 15, 63)
b = r4(b, c, d, a, 9, 21, 64)
a = stadd(a, aa)
b = stadd(b, bb)
c = stadd(c, cc)
d = stadd(d, dd)
NEXT
'sitten vaihdetaan heksoiksi
a = bintohex(a)
b = bintohex(b)
c = bintohex(c)
d = bintohex(d)
'vaihdetaan tavujarjestysta, siksi vahan hassu :o
FOR i = 1 TO 4
FOR j = 7 TO 1 STEP -2
IF i = 1 THEN PRINT MID$(a, j, 2);
IF i = 2 THEN PRINT MID$(b, j, 2);
IF i = 3 THEN PRINT MID$(c, j, 2);
IF i = 4 THEN PRINT MID$(d, j, 2);
NEXT
NEXT
'muuttaa merkkijonon binaariluvuksi
FUNCTION asctobin$ (a AS STRING)
d$ = ""
FOR i = 1 TO LEN(a)
b$ = ""
c = ASC(MID$(a, i, 1))
p = 0
WHILE c > 0
b$ = b$ + CHR$((c MOD 2) + 48)
c = c \ 2
p = p + 1
WEND
FOR j = p TO 7
b$ = b$ + "0"
NEXT
FOR j = 8 TO 1 STEP -1
d$ = d$ + MID$(b$, j, 1)
NEXT
NEXT
asctobin$ = d$
END FUNCTION
FUNCTION bintohex$ (a AS STRING)
b$ = ""
DIM c(16) AS STRING
c(1) = "0000"
c(2) = "0001"
c(3) = "0010"
c(4) = "0011"
c(5) = "0100"
c(6) = "0101"
c(7) = "0110"
c(8) = "0111"
c(9) = "1000"
c(10) = "1001"
c(11) = "1010"
c(12) = "1011"
c(13) = "1100"
c(14) = "1101"
c(15) = "1110"
c(16) = "1111"
d$ = "abcdef"
FOR i = 1 TO LEN(a) STEP 4
FOR j = 1 TO 16
IF MID$(a, i, 4) = c(j) THEN
IF j < 11 THEN
b$ = b$ + CHR$(j - 1 + 48)
ELSE
b$ = b$ + MID$(d$, j - 10, 1)
END IF
END IF
NEXT
NEXT
bintohex$ = b$
END FUNCTION
FUNCTION flol$ (a AS STRING, b AS STRING, c AS STRING)
flol$ = sor(sand(a, b), sand(snot(a), c))
END FUNCTION
FUNCTION glol$ (a AS STRING, b AS STRING, c AS STRING)
glol$ = sor(sand(a, c), sand(b, snot(c)))
END FUNCTION
FUNCTION hextobin$ (a AS STRING)
d$ = ""
DIM e(16) AS STRING
e(1) = "0000"
e(2) = "0001"
e(3) = "0010"
e(4) = "0011"
e(5) = "0100"
e(6) = "0101"
e(7) = "0110"
e(8) = "0111"
e(9) = "1000"
e(10) = "1001"
e(11) = "1010"
e(12) = "1011"
e(13) = "1100"
e(14) = "1101"
e(15) = "1110"
e(16) = "1111"
FOR i = 1 TO LEN(a)
c = ASC(MID$(a, i, 1))
IF c > 64 THEN
d$ = d$ + e(c - 86)
ELSE
d$ = d$ + e(c - 47)
END IF
NEXT
hextobin$ = d$
END FUNCTION
FUNCTION hlol$ (a AS STRING, b AS STRING, c AS STRING)
hlol$ = sxor(a, sxor(b, c))
END FUNCTION
FUNCTION ilol$ (a AS STRING, b AS STRING, c AS STRING)
ilol$ = sxor(b, sor(a, snot(c)))
END FUNCTION
FUNCTION lrotate$ (a AS STRING, b AS LONG)
DIM c AS STRING
c = a
FOR i = 0 TO LEN(a) - 1
MID$(c, i + 1) = MID$(a, (i + b) MOD LEN(a) + 1, 1)
NEXT
lrotate$ = c
END FUNCTION
FUNCTION r1$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, i AS LONG)
r1$ = stadd(b, lrotate(stadd(stadd(a, flol(b, c, d)), stadd(x(k), t(i))), s))
END FUNCTION
FUNCTION r2$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, i AS LONG)
r2$ = stadd(b, lrotate(stadd(stadd(a, glol(b, c, d)), stadd(x(k), t(i))), s))
END FUNCTION
FUNCTION r3$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, i AS LONG)
r3$ = stadd(b, lrotate(stadd(stadd(a, hlol(b, c, d)), stadd(x(k), t(i))), s))
END FUNCTION
FUNCTION r4$ (a AS STRING, b AS STRING, c AS STRING, d AS STRING, k AS LONG, s AS LONG, i AS LONG)
r4$ = stadd(b, lrotate(stadd(stadd(a, ilol(b, c, d)), stadd(x(k), t(i))), s))
END FUNCTION
'bitwise and
FUNCTION sand$ (a AS STRING, b AS STRING)
DIM c AS STRING
c = a
FOR i = 1 TO LEN(a)
IF (MID$(a, i, 1) = "1") AND (MID$(b, i, 1) = "1") THEN
MID$(c, i) = "1"
ELSE
MID$(c, i) = "0"
END IF
NEXT
sand$ = c
END FUNCTION
'bitwise not
FUNCTION snot$ (a AS STRING)
DIM b AS STRING
b = a
FOR i = 1 TO LEN(a)
IF MID$(a, i, 1) = "1" THEN
MID$(b, i) = "0"
ELSE
MID$(b, i) = "1"
END IF
NEXT
snot$ = b
END FUNCTION
'bitwise or
FUNCTION sor$ (a AS STRING, b AS STRING)
DIM c AS STRING
c = a
FOR i = 1 TO LEN(a)
IF (MID$(a, i, 1) = "1") OR (MID$(b, i, 1) = "1") THEN
MID$(c, i) = "1"
ELSE
MID$(c, i) = "0"
END IF
NEXT
sor$ = c
END FUNCTION
'kahden binaariluvun lisaaminen modulo 2^32
FUNCTION stadd$ (a AS STRING, b AS STRING)
DIM c AS STRING
c = b
d = 0
FOR i = LEN(a) TO 1 STEP -1
e = 0
IF d = 1 THEN e = e + 1
IF MID$(a, i, 1) = "1" THEN e = e + 1
IF MID$(b, i, 1) = "1" THEN e = e + 1
IF e = 3 THEN MID$(c, i) = "1"
IF e = 2 THEN
MID$(c, i) = "0"
d = 1
END IF
IF e = 1 THEN
MID$(c, i) = "1"
d = 0
END IF
NEXT
stadd$ = c
END FUNCTION
'bitwise xor
FUNCTION sxor$ (a AS STRING, b AS STRING)
DIM c AS STRING
c = a
FOR i = 1 TO LEN(a)
IF MID$(a, i, 1) = MID$(b, i, 1) THEN
MID$(c, i) = "0"
ELSE
MID$(c, i) = "1"
END IF
NEXT
sxor$ = c
END FUNCTIONVoisit kyllä muuttaa tuon käyttämään lukuja. Ei ole mitään syytä laskea teksteillä.