Hace un par de días me interesó traducir el algoritmo SHA256 (Secure Hash Algorithm (https://es.wikipedia.org/wiki/Secure_Hash_Algorithm)) a Cramel para demostrar su potencia, así que acá les dejo el algoritmo.
Importar "Cramel.cml"
Var m_lOnBits[31]:Entero
Var SHA_K[64]:Entero
Const BITS_TO_A_BYTE = 8
Const BYTES_TO_A_WORD = 4
Const BITS_TO_A_WORD = 32
Proc InicializarSHA256
m_lOnBits[0] = 1 ' 00000000000000000000000000000001
m_lOnBits[1] = 3 ' 00000000000000000000000000000011
m_lOnBits[2] = 7 ' 00000000000000000000000000000111
m_lOnBits[3] = 15 ' 00000000000000000000000000001111
m_lOnBits[4] = 31 ' 00000000000000000000000000011111
m_lOnBits[5] = 63 ' 00000000000000000000000000111111
m_lOnBits[6] = 127 ' 00000000000000000000000001111111
m_lOnBits[7] = 255 ' 00000000000000000000000011111111
m_lOnBits[8] = 511 ' 00000000000000000000000111111111
m_lOnBits[9] = 1023 ' 00000000000000000000001111111111
m_lOnBits[10] = 2047 ' 00000000000000000000011111111111
m_lOnBits[11] = 4095 ' 00000000000000000000111111111111
m_lOnBits[12] = 8191 ' 00000000000000000001111111111111
m_lOnBits[13] = 16383 ' 00000000000000000011111111111111
m_lOnBits[14] = 32767 ' 00000000000000000111111111111111
m_lOnBits[15] = 65535 ' 00000000000000001111111111111111
m_lOnBits[16] = 131071 ' 00000000000000011111111111111111
m_lOnBits[17] = 262143 ' 00000000000000111111111111111111
m_lOnBits[18] = 524287 ' 00000000000001111111111111111111
m_lOnBits[19] = 1048575 ' 00000000000011111111111111111111
m_lOnBits[20] = 2097151 ' 00000000000111111111111111111111
m_lOnBits[21] = 4194303 ' 00000000001111111111111111111111
m_lOnBits[22] = 8388607 ' 00000000011111111111111111111111
m_lOnBits[23] = 16777215 ' 00000000111111111111111111111111
m_lOnBits[24] = 33554431 ' 00000001111111111111111111111111
m_lOnBits[25] = 67108863 ' 00000011111111111111111111111111
m_lOnBits[26] = 134217727 ' 00000111111111111111111111111111
m_lOnBits[27] = 268435455 ' 00001111111111111111111111111111
m_lOnBits[28] = 536870911 ' 00011111111111111111111111111111
m_lOnBits[29] = 1073741823 ' 00111111111111111111111111111111
m_lOnBits[30] = 2147483647 ' 01111111111111111111111111111111
SHA_K[0] = &428A2F98
SHA_K[1] = &71374491
SHA_K[2] = &B5C0FBCF
SHA_K[3] = &E9B5DBA5
SHA_K[4] = &3956C25B
SHA_K[5] = &59F111F1
SHA_K[6] = &923F82A4
SHA_K[7] = &AB1C5ED5
SHA_K[8] = &D807AA98
SHA_K[9] = &12835B01
SHA_K[10] = &243185BE
SHA_K[11] = &550C7DC3
SHA_K[12] = &72BE5D74
SHA_K[13] = &80DEB1FE
SHA_K[14] = &9BDC06A7
SHA_K[15] = &C19BF174
SHA_K[16] = &E49B69C1
SHA_K[17] = &EFBE4786
SHA_K[18] = &FC19DC6
SHA_K[19] = &240CA1CC
SHA_K[20] = &2DE92C6F
SHA_K[21] = &4A7484AA
SHA_K[22] = &5CB0A9DC
SHA_K[23] = &76F988DA
SHA_K[24] = &983E5152
SHA_K[25] = &A831C66D
SHA_K[26] = &B00327C8
SHA_K[27] = &BF597FC7
SHA_K[28] = &C6E00BF3
SHA_K[29] = &D5A79147
SHA_K[30] = &6CA6351
SHA_K[31] = &14292967
SHA_K[32] = &27B70A85
SHA_K[33] = &2E1B2138
SHA_K[34] = &4D2C6DFC
SHA_K[35] = &53380D13
SHA_K[36] = &650A7354
SHA_K[37] = &766A0ABB
SHA_K[38] = &81C2C92E
SHA_K[39] = &92722C85
SHA_K[40] = &A2BFE8A1
SHA_K[41] = &A81A664B
SHA_K[42] = &C24B8B70
SHA_K[43] = &C76C51A3
SHA_K[44] = &D192E819
SHA_K[45] = &D6990624
SHA_K[46] = &F40E3585
SHA_K[47] = &106AA070
SHA_K[48] = &19A4C116
SHA_K[49] = &1E376C08
SHA_K[50] = &2748774C
SHA_K[51] = &34B0BCB5
SHA_K[52] = &391C0CB3
SHA_K[53] = &4ED8AA4A
SHA_K[54] = &5B9CCA4F
SHA_K[55] = &682E6FF3
SHA_K[56] = &748F82EE
SHA_K[57] = &78A5636F
SHA_K[58] = &84C87814
SHA_K[59] = &8CC70208
SHA_K[60] = &90BEFFFA
SHA_K[61] = &A4506CEB
SHA_K[62] = &BEF9A3F7
SHA_K[63] = &C67178F2
FinProc
Proc AddUnsigned(lX,lY:Entero):Entero
Var lX8,lY8,lX4,lY4:Entero
lX8 = lX And &80000000
lY8 = lY And &80000000
lX4 = lX And &40000000
lY4 = lY And &40000000
Resultado = (lX And &3FFFFFFF) + (lY And &3FFFFFFF)
Si lX4 And lY4 Entonces
Resultado = Resultado Xor &80000000 Xor lX8 Xor lY8
OSi lX4 Or lY4 Entonces
Si Resultado And &40000000 Entonces
Resultado = Resultado Xor &C0000000 Xor lX8 Xor lY8
SiNo
Resultado = Resultado Xor &40000000 Xor lX8 Xor lY8
FinSi
SiNo
Resultado = Resultado Xor lX8 Xor lY8
FinSi
FinProc
Proc Ch(X,Y,Z:Entero):Entero
Resultado = (X And Y) Xor ((Not X) And Z)
FinProc
Proc Maj(X,Y,Z:Entero):Entero
Resultado = (X And Y) Xor (X And Z) Xor (Y And Z)
FinProc
Proc S(X,N:Entero):Entero
Resultado = (X Shr (N And m_lOnBits[4])) Or (X Shl (32 - (N And m_lOnBits[4])))
FinProc
Proc R(X,N:Entero):Entero
Resultado = X Shr (N And m_lOnBits[4])
FinProc
Proc Sigma0(X:Entero):Entero
Resultado = S(X,2) Xor S(X,13) Xor S(X,22)
FinProc
Proc Sigma1(X:Entero):Entero
Resultado = S(X,6) Xor S(X,11) Xor S(X,25)
FinProc
Proc Gamma0(X:Entero):Entero
Resultado = S(X,7) Xor S(X,18) Xor R(X,3)
FinProc
Proc Gamma1(X:Entero):Entero
Resultado = S(X,17) Xor S(X,19) Xor R(X,10)
FinProc
Proc ConvertToWordArray(Referencia sMessage:Cadena):Entero[]
Var lMessageLength:Entero
Var lNumberOfWords:Entero
Var lBytePosition:Entero
Var lByteCount:Entero
Var lWordCount:Entero
Var lByte:Entero
Var @p:Byte
Const MODULUS_BITS = 512
Const CONGRUENT_BITS = 448
lMessageLength = CadLong(sMessage)
lNumberOfWords = (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) \ BITS_TO_A_BYTE)) \ (MODULUS_BITS \ BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS \ BITS_TO_A_WORD)
ReDim Resultado,lNumberOfWords-1
Mientras lByteCount < lMessageLength
lWordCount = lByteCount \ BYTES_TO_A_WORD
lBytePosition = (3 - (lByteCount Mod BYTES_TO_A_WORD)) * BITS_TO_A_BYTE
p@ = sMessage@@+lByteCount
lByte = p
Resultado[lWordCount] = Resultado[lWordCount] Or (lByte Shl lBytePosition)
lByteCount = lByteCount + 1
FinMientras
lWordCount = lByteCount \ BYTES_TO_A_WORD
lBytePosition = (3 - (lByteCount Mod BYTES_TO_A_WORD)) * BITS_TO_A_BYTE
Resultado[lWordCount] = Resultado[lWordCount] Or (&80 Shl lBytePosition)
Resultado[lNumberOfWords-1] = lMessageLength Shl 3
Resultado[lNumberOfWords-2] = lMessageLength Shr 29
FinProc
Proc AnsiASHA256(Referencia cMessage:Cadena):Cadena
Var HASH[8]:Entero
Var M[]:Entero
Var W[64]:Entero
Var a,b,c,d,e,f,g,h,i,j,T1,T2:Entero
HASH[0] = &6A09E667
HASH[1] = &BB67AE85
HASH[2] = &3C6EF372
HASH[3] = &A54FF53A
HASH[4] = &510E527F
HASH[5] = &9B05688C
HASH[6] = &1F83D9AB
HASH[7] = &5BE0CD19
M = ConvertToWordArray(cMessage)
Contar i a (&M) Paso 16
Si i > &M Entonces Salir Contar
a = HASH[0]
b = HASH[1]
c = HASH[2]
d = HASH[3]
e = HASH[4]
f = HASH[5]
g = HASH[6]
h = HASH[7]
j = 0
Contar j a 63
Si j < 16 Entonces
W[j] = M[j+i]
SiNo
W[j] = AddUnsigned(AddUnsigned(AddUnsigned(Gamma1(W[j-2]),W[j-7]),Gamma0(W[j-15])),W[j - 16])
FinSi
T1 = AddUnsigned(AddUnsigned(AddUnsigned(AddUnsigned(h, Sigma1(e)),Ch(e, f, g)), SHA_K[j]), W[j])
T2 = AddUnsigned(Sigma0(a),Maj(a,b,c))
h = g
g = f
f = e
e = AddUnsigned(d, T1)
d = c
c = b
b = a
a = AddUnsigned(T1, T2)
Seguir
HASH[0] = AddUnsigned(a, HASH[0])
HASH[1] = AddUnsigned(b, HASH[1])
HASH[2] = AddUnsigned(c, HASH[2])
HASH[3] = AddUnsigned(d, HASH[3])
HASH[4] = AddUnsigned(e, HASH[4])
HASH[5] = AddUnsigned(f, HASH[5])
HASH[6] = AddUnsigned(g, HASH[6])
HASH[7] = AddUnsigned(h, HASH[7])
Seguir
Resultado = EntCad(HASH[0],16) + EntCad(HASH[1],16) + EntCad(HASH[2],16) + _
EntCad(HASH[3],16) + EntCad(HASH[4],16) + EntCad(HASH[5],16) + _
EntCad(HASH[6],16) + EntCad(HASH[7],16)
FinProc
InicializarSHA256
MessageBox(0,AnsiASHA256("abc"),"Cramel",48)
También lo pueden ver desde aquí (https://cramel.org/sha-256/).
¡Saludos!
Hola, no tendrás el algoritmo en el lenguaje original?