107 lines
2.7 KiB
Plaintext
107 lines
2.7 KiB
Plaintext
' version 18-10-2016
|
|
' started with SHA-1/FIPS-180-1
|
|
' but used the BBC BASIC native version to finish.
|
|
' compile with: fbc -s console
|
|
|
|
Function SHA_1(test_str As String) As String
|
|
|
|
Dim As String message = test_str ' strings are passed as ByRef's
|
|
|
|
Dim As Long i, j
|
|
Dim As UByte Ptr ww1
|
|
Dim As UInteger<32> Ptr ww4
|
|
|
|
Dim As ULongInt l = Len(message)
|
|
' set the first bit after the message to 1
|
|
message = message + Chr(1 Shl 7)
|
|
' add one char to the length
|
|
Dim As ULong padding = 64 - ((l +1) Mod (512 \ 8)) ' 512 \ 8 = 64 char.
|
|
|
|
' check if we have enough room for inserting the length
|
|
If padding < 8 Then padding = padding + 64
|
|
|
|
message = message + String(padding, Chr(0)) ' adjust length
|
|
Dim As ULong l1 = Len(message) ' new length
|
|
|
|
l = l * 8 ' orignal length in bits
|
|
' create ubyte ptr to point to l ( = length in bits)
|
|
Dim As UByte Ptr ub_ptr = Cast(UByte Ptr, @l)
|
|
|
|
For i = 0 To 7 'copy length of message to the last 8 bytes
|
|
message[l1 -1 - i] = ub_ptr[i]
|
|
Next
|
|
|
|
Dim As UInteger<32> A, B, C, D, E, k, temp, W(0 To 79)
|
|
Dim As UInteger<32> H0 = &H67452301
|
|
Dim As UInteger<32> H1 = &HEFCDAB89
|
|
Dim As UInteger<32> H2 = &H98BADCFE
|
|
Dim As UInteger<32> H3 = &H10325476
|
|
Dim As UInteger<32> H4 = &HC3D2E1F0
|
|
|
|
|
|
For j = 0 To (l1 -1) \ 64 ' split into block of 64 bytes
|
|
ww1 = Cast(Ubyte Ptr, @message[j * 64])
|
|
ww4 = Cast(UInteger<32> Ptr, @message[j * 64])
|
|
|
|
For i = 0 To 60 Step 4 'little endian -> big endian
|
|
Swap ww1[i ], ww1[i +3]
|
|
Swap ww1[i +1], ww1[i +2]
|
|
Next
|
|
|
|
For i = 0 To 15 ' copy the 16 32bit block into the array
|
|
W(i) = ww4[i]
|
|
Next
|
|
|
|
For i = 16 To 79 ' fill the rest of the array
|
|
temp = W(i -3) Xor W(i -8) Xor W(i -14) Xor W(i -16)
|
|
temp = temp Shl 1 + temp Shr 31
|
|
W(i) = temp
|
|
Next
|
|
|
|
A = h0 : B = h1 : C = h2 : D = h3 : E = h4
|
|
|
|
For i = 0 To 79
|
|
Select Case As Const i
|
|
Case 0 To 19
|
|
temp = (B And C) or ((Not B) And D)
|
|
k = &H5A827999
|
|
Case 20 To 39
|
|
temp = B Xor C Xor D
|
|
k = &H6ED9EBA1
|
|
Case 40 To 59
|
|
temp = (B And C) Or (B And D) Or (C And D)
|
|
k = &H8F1BBCDC
|
|
Case 60 To 79
|
|
temp = B Xor C Xor D
|
|
k = &hCA62C1D6
|
|
End Select
|
|
|
|
temp = A Shl 5 + A Shr 27 + temp + E + k + W(i)
|
|
E = D
|
|
D = C
|
|
C = (B Shl 30) or (B Shr 2)
|
|
B = A
|
|
A = temp
|
|
|
|
Next
|
|
|
|
h0 += A : h1 += B : h2 += C : h3 += D : h4 += E
|
|
|
|
Next
|
|
|
|
Return Hex(h0, 8) + Hex(h1, 8) + Hex(h2, 8) + Hex(h3, 8) + Hex(h4, 8)
|
|
|
|
End Function
|
|
|
|
' ------=< MAIN >=------
|
|
|
|
Dim As String test = "Rosetta Code"
|
|
Print test; " => "; SHA_1(test)
|
|
|
|
|
|
' empty keyboard buffer
|
|
While InKey <> "" : Wend
|
|
Print : Print "hit any key to end program"
|
|
Sleep
|
|
End
|