Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
150
Task/MD5-Implementation/FreeBASIC/md5-implementation.freebasic
Normal file
150
Task/MD5-Implementation/FreeBASIC/md5-implementation.freebasic
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
' version 19-10-2016
|
||||
' MD5 from the Wikipedia page "MD5"
|
||||
' compile with: fbc -s console
|
||||
|
||||
' macro for a rotate left
|
||||
#Macro ROtate_Left (x, n) ' rotate left
|
||||
(x) = (x) Shl (n) + (x) Shr (32 - (n))
|
||||
#EndMacro
|
||||
|
||||
Function MD5(test_str As String) As String
|
||||
|
||||
Dim As String message = test_str ' strings are passed as ByRef's
|
||||
|
||||
Dim As UByte sx, s(0 To ...) = { 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, _
|
||||
17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, _
|
||||
5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, _
|
||||
16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }
|
||||
|
||||
Dim As UInteger<32> K(0 To ...) = { &Hd76aa478, &He8c7b756, &H242070db, _
|
||||
&Hc1bdceee, &Hf57c0faf, &H4787c62a, &Ha8304613, &Hfd469501, &H698098d8, _
|
||||
&H8b44f7af, &Hffff5bb1, &H895cd7be, &H6b901122, &Hfd987193, &Ha679438e, _
|
||||
&H49b40821, &Hf61e2562, &Hc040b340, &H265e5a51, &He9b6c7aa, &Hd62f105d, _
|
||||
&H02441453, &Hd8a1e681, &He7d3fbc8, &H21e1cde6, &Hc33707d6, &Hf4d50d87, _
|
||||
&H455a14ed, &Ha9e3e905, &Hfcefa3f8, &H676f02d9, &H8d2a4c8a, &Hfffa3942, _
|
||||
&H8771f681, &H6d9d6122, &Hfde5380c, &Ha4beea44, &H4bdecfa9, &Hf6bb4b60, _
|
||||
&Hbebfbc70, &H289b7ec6, &Heaa127fa, &Hd4ef3085, &H04881d05, &Hd9d4d039, _
|
||||
&He6db99e5, &H1fa27cf8, &Hc4ac5665, &Hf4292244, &H432aff97, &Hab9423a7, _
|
||||
&Hfc93a039, &H655b59c3, &H8f0ccc92, &Hffeff47d, &H85845dd1, &H6fa87e4f, _
|
||||
&Hfe2ce6e0, &Ha3014314, &H4e0811a1, &Hf7537e82, &Hbd3af235, &H2ad7d2bb, _
|
||||
&Heb86d391 }
|
||||
|
||||
' Initialize variables
|
||||
Dim As UInteger<32> A, a0 = &H67452301
|
||||
Dim As UInteger<32> B, b0 = &Hefcdab89
|
||||
Dim As UInteger<32> C, c0 = &H98badcfe
|
||||
Dim As UInteger<32> D, d0 = &H10325476
|
||||
Dim As UInteger<32> dtemp, F, g, temp
|
||||
|
||||
Dim As Long i, j
|
||||
|
||||
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 -8 + i] = ub_ptr[i]
|
||||
Next
|
||||
|
||||
For j = 0 To (l1 -1) \ 64 ' split into block of 64 bytes
|
||||
|
||||
A = a0 : B = b0 : C = c0 : D = d0
|
||||
|
||||
' break chunk into 16 32bit uinteger
|
||||
Dim As UInteger<32> Ptr M = Cast(UInteger<32> Ptr, @message[j * 64])
|
||||
|
||||
For i = 0 To 63
|
||||
Select Case As Const i
|
||||
Case 0 To 15
|
||||
F = (B And C) Or ((Not B) And D)
|
||||
g = i
|
||||
Case 16 To 31
|
||||
F = (B And D) Or (C And (Not D))
|
||||
g = (i * 5 +1) Mod 16
|
||||
Case 32 To 47
|
||||
F = (B Xor C Xor D)
|
||||
g = (i * 3 +5) Mod 16
|
||||
Case 48 To 63
|
||||
F = C Xor (B Or (Not D))
|
||||
g = (i * 7) Mod 16
|
||||
End Select
|
||||
dtemp = D
|
||||
D = C
|
||||
C = B
|
||||
temp = A + F + K(i)+ M[g] : ROtate_left(temp, s(i))
|
||||
B = B + temp
|
||||
A = dtemp
|
||||
Next
|
||||
|
||||
a0 += A : b0 += B : c0 += C : d0 += D
|
||||
|
||||
Next
|
||||
|
||||
Dim As String answer
|
||||
' convert a0, b0, c0 and d0 in hex, then add, low order first
|
||||
Dim As String s1 = Hex(a0, 8)
|
||||
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
|
||||
s1 = Hex(b0, 8)
|
||||
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
|
||||
s1 = Hex(c0, 8)
|
||||
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
|
||||
s1 = Hex(d0, 8)
|
||||
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
|
||||
|
||||
Return LCase(answer)
|
||||
|
||||
End Function
|
||||
|
||||
|
||||
' ------=< MAIN >=------
|
||||
|
||||
Dim As String test, hash, md5_hash
|
||||
Dim As ULong i
|
||||
|
||||
For i = 1 To 7
|
||||
Read hash, test
|
||||
md5_hash = MD5(test)
|
||||
|
||||
Print
|
||||
Print test
|
||||
Print hash
|
||||
Print md5_hash;
|
||||
|
||||
If hash = md5_hash Then
|
||||
Print " PASS"
|
||||
Else
|
||||
Print " FAIL"
|
||||
Beep
|
||||
End If
|
||||
|
||||
Next
|
||||
|
||||
' testdata
|
||||
Data "d41d8cd98f00b204e9800998ecf8427e", ""
|
||||
Data "0cc175b9c0f1b6a831c399e269772661", "a"
|
||||
Data "900150983cd24fb0d6963f7d28e17f72", "abc"
|
||||
Data "f96b697d7cb7938d525a2f31aaf161d0", "message digest"
|
||||
Data "c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz"
|
||||
Data "d174ab98d277d9f5a5611c2c9f419d9f"
|
||||
Data "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
Data "57edf4a22be3c955ac49da2e2107b67a"
|
||||
Data "123456789012345678901234567890123456789012345678901234567890" _
|
||||
+ "12345678901234567890"
|
||||
|
||||
' empty keyboard buffer
|
||||
While InKey <> "" : Wend
|
||||
Print : Print "hit any key to end program"
|
||||
Sleep
|
||||
End
|
||||
143
Task/MD5-Implementation/Phix/md5-implementation.phix
Normal file
143
Task/MD5-Implementation/Phix/md5-implementation.phix
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
function uxor(atom data1,atom data2)
|
||||
atom result = xor_bits(data1,data2)
|
||||
if result<0 then result += #100000000 end if
|
||||
return result
|
||||
end function
|
||||
|
||||
function uor(atom data1,atom data2)
|
||||
atom result = or_bits(data1,data2)
|
||||
if result<0 then result += #100000000 end if
|
||||
return result
|
||||
end function
|
||||
|
||||
function r32(atom a)
|
||||
return remainder(a,#100000000)
|
||||
end function
|
||||
|
||||
function rol(atom word,integer bits)
|
||||
-- left rotate the bits of a 32-bit number by the specified number of bits
|
||||
return r32(word*power(2,bits))+floor(word/power(2,32-bits))
|
||||
end function
|
||||
|
||||
constant K =
|
||||
{#d76aa478, #e8c7b756, #242070db, #c1bdceee, #f57c0faf, #4787c62a, #a8304613, #fd469501,
|
||||
#698098d8, #8b44f7af, #ffff5bb1, #895cd7be, #6b901122, #fd987193, #a679438e, #49b40821,
|
||||
#f61e2562, #c040b340, #265e5a51, #e9b6c7aa, #d62f105d, #02441453, #d8a1e681, #e7d3fbc8,
|
||||
#21e1cde6, #c33707d6, #f4d50d87, #455a14ed, #a9e3e905, #fcefa3f8, #676f02d9, #8d2a4c8a,
|
||||
#fffa3942, #8771f681, #6d9d6122, #fde5380c, #a4beea44, #4bdecfa9, #f6bb4b60, #bebfbc70,
|
||||
#289b7ec6, #eaa127fa, #d4ef3085, #04881d05, #d9d4d039, #e6db99e5, #1fa27cf8, #c4ac5665,
|
||||
#f4292244, #432aff97, #ab9423a7, #fc93a039, #655b59c3, #8f0ccc92, #ffeff47d, #85845dd1,
|
||||
#6fa87e4f, #fe2ce6e0, #a3014314, #4e0811a1, #f7537e82, #bd3af235, #2ad7d2bb, #eb86d391}
|
||||
|
||||
constant m_block = {1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
|
||||
2, 7,12, 1, 6,11,16, 5,10,15, 4, 9,14, 3, 8,13,
|
||||
6, 9,12,15, 2, 5, 8,11,14, 1, 4, 7,10,13,16, 3,
|
||||
1, 8,15, 6,13, 4,11, 2, 9,16, 7,14, 5,12, 3,10}
|
||||
|
||||
constant c_words = {#67452301,#efcdab89,#98badcfe,#10325476}
|
||||
|
||||
sequence words
|
||||
|
||||
function divide_in_words(sequence message)
|
||||
-- Divides the string into words (32-bit numbers)
|
||||
sequence res
|
||||
res = repeat(0,length(message)/4)
|
||||
for word=1 to length(message)/4 do
|
||||
res[word] = bytes_to_int(message[word*4-3..word*4])
|
||||
end for
|
||||
return res
|
||||
end function
|
||||
|
||||
procedure process_block(sequence block)
|
||||
-- Updates the words according to the contents of the block
|
||||
atom a,b,c,d
|
||||
|
||||
block = divide_in_words(block)
|
||||
|
||||
a = words[1]
|
||||
b = words[2]
|
||||
c = words[3]
|
||||
d = words[4]
|
||||
|
||||
-- Round 1
|
||||
for step=1 to 16 by 4 do
|
||||
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uor(and_bits(b,c),and_bits(not_bits(b),d))), 7))
|
||||
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uor(and_bits(a,b),and_bits(not_bits(a),c))),12))
|
||||
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uor(and_bits(d,a),and_bits(not_bits(d),b))),17))
|
||||
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uor(and_bits(c,d),and_bits(not_bits(c),a))),22))
|
||||
end for
|
||||
|
||||
-- Round 2
|
||||
for step=17 to 32 by 4 do
|
||||
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uor(and_bits(b,d),and_bits(c,not_bits(d)))), 5))
|
||||
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uor(and_bits(a,c),and_bits(b,not_bits(c)))), 9))
|
||||
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uor(and_bits(d,b),and_bits(a,not_bits(b)))),14))
|
||||
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uor(and_bits(c,a),and_bits(d,not_bits(a)))),20))
|
||||
end for
|
||||
|
||||
-- Round 3
|
||||
for step=33 to 48 by 4 do
|
||||
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uxor(b,xor_bits(c,d))), 4))
|
||||
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uxor(a,xor_bits(b,c))),11))
|
||||
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uxor(d,xor_bits(a,b))),16))
|
||||
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uxor(c,xor_bits(d,a))),23))
|
||||
end for
|
||||
|
||||
-- Round 4
|
||||
for step=49 to 64 by 4 do
|
||||
a = r32(b+rol(r32(a+block[m_block[step ]]+K[step ]+uxor(c,or_bits(b,not_bits(d)))), 6))
|
||||
d = r32(a+rol(r32(d+block[m_block[step+1]]+K[step+1]+uxor(b,or_bits(a,not_bits(c)))),10))
|
||||
c = r32(d+rol(r32(c+block[m_block[step+2]]+K[step+2]+uxor(a,or_bits(d,not_bits(b)))),15))
|
||||
b = r32(c+rol(r32(b+block[m_block[step+3]]+K[step+3]+uxor(d,or_bits(c,not_bits(a)))),21))
|
||||
end for
|
||||
|
||||
-- Update the words
|
||||
words[1] = r32(words[1]+a)
|
||||
words[2] = r32(words[2]+b)
|
||||
words[3] = r32(words[3]+c)
|
||||
words[4] = r32(words[4]+d)
|
||||
end procedure
|
||||
|
||||
function pad_message(sequence message)
|
||||
-- Add bytes to the end of the message so it can be divided
|
||||
-- in an exact number of 64-byte blocks.
|
||||
integer bytes_to_add
|
||||
bytes_to_add = 64-remainder(length(message)+9,64)
|
||||
if bytes_to_add=64 then bytes_to_add = 0 end if
|
||||
|
||||
message = messageP&repeat(0,bytes_to_add)&
|
||||
int_to_bytes(length(message)*8)&{0,0,0,0}
|
||||
|
||||
return message
|
||||
end function
|
||||
|
||||
|
||||
function md5(sequence message)
|
||||
-- Given a string, returns a 16-byte hash of it.
|
||||
|
||||
words = c_words -- Initialize the H words
|
||||
|
||||
message = pad_message(message) -- Add bytes to the message
|
||||
|
||||
-- Process each 64-byte block
|
||||
for block=1 to length(message) by 64 do
|
||||
process_block(message[block..block+63])
|
||||
end for
|
||||
|
||||
-- Convert hash into bytes
|
||||
return int_to_bytes(words[1])& -- Return the hash
|
||||
int_to_bytes(words[2])&
|
||||
int_to_bytes(words[3])&
|
||||
int_to_bytes(words[4])
|
||||
|
||||
end function
|
||||
|
||||
constant fmt = "0x%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n"
|
||||
|
||||
printf(1,fmt,md5(""))
|
||||
printf(1,fmt,md5("a"))
|
||||
printf(1,fmt,md5("abc"))
|
||||
printf(1,fmt,md5("message digest"))
|
||||
printf(1,fmt,md5("abcdefghijklmnopqrstuvwxyz"))
|
||||
printf(1,fmt,md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"))
|
||||
printf(1,fmt,md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890"))
|
||||
109
Task/MD5-Implementation/Sidef/md5-implementation.sidef
Normal file
109
Task/MD5-Implementation/Sidef/md5-implementation.sidef
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
class MD5(String msg) {
|
||||
|
||||
method init {
|
||||
msg = msg.bytes
|
||||
}
|
||||
|
||||
const FGHI = [
|
||||
{|a,b,c| (a & b) | (~a & c) },
|
||||
{|a,b,c| (a & c) | (b & ~c) },
|
||||
{|a,b,c| (a ^ b ^ c) },
|
||||
{|a,b,c| (b ^ (a | ~c)) },
|
||||
]
|
||||
|
||||
const S = [
|
||||
[7, 12, 17, 22] * 4,
|
||||
[5, 9, 14, 20] * 4,
|
||||
[4, 11, 16, 23] * 4,
|
||||
[6, 10, 15, 21] * 4,
|
||||
].flat
|
||||
|
||||
const T = 64.of {|i| floor(abs(sin(i)) * 1<<32) }
|
||||
|
||||
const K = [
|
||||
^16 -> map {|n| n },
|
||||
^16 -> map {|n| (5*n + 1) % 16 },
|
||||
^16 -> map {|n| (3*n + 5) % 16 },
|
||||
^16 -> map {|n| (7*n ) % 16 },
|
||||
].flat
|
||||
|
||||
func radix(Number b, Array a) {
|
||||
^a -> map {|i| b**i * a[i] }.sum(0)
|
||||
}
|
||||
|
||||
func little_endian(Number w, Number n, Array v) {
|
||||
var step1 = (^n »*» w)
|
||||
var step2 = (v ~X>> step1)
|
||||
step2 »%» (1 << w)
|
||||
}
|
||||
|
||||
func block(Number a, Number b) { (a + b) & 0xffffffff }
|
||||
func srble(Number a, Number n) { (a << n) & 0xffffffff | (a >> (32-n)) }
|
||||
|
||||
func md5_pad(msg) {
|
||||
var bits = 8*msg.len
|
||||
var padded = [msg..., 128, [0] * (-(floor(bits / 8) + 1 + 8) % 64)].flat
|
||||
|
||||
gather {
|
||||
padded.each_slice(4, {|a|
|
||||
take(radix(256, a))
|
||||
})
|
||||
take(little_endian(32, 2, [bits]))
|
||||
}.flat
|
||||
}
|
||||
|
||||
func md5_block(Array H, Array X) {
|
||||
var (A, B, C, D) = H...
|
||||
|
||||
for i in ^64 {
|
||||
(A, B, C, D) = (D,
|
||||
block(B, srble(
|
||||
block(
|
||||
block(
|
||||
block(A, FGHI[floor(i / 16)](B, C, D)), T[i]
|
||||
), X[K[i]]
|
||||
), S[i])
|
||||
), B, C)
|
||||
}
|
||||
|
||||
for k,v in ([A, B, C, D].pairs) {
|
||||
H[k] = block(H[k], v)
|
||||
}
|
||||
|
||||
return H
|
||||
}
|
||||
|
||||
method md5_hex {
|
||||
self.md5.map {|n| '%02x' % n }.join
|
||||
}
|
||||
|
||||
method md5 {
|
||||
var M = md5_pad(msg)
|
||||
var H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]
|
||||
|
||||
for i in (range(0, M.end, 16)) {
|
||||
md5_block(H, M.ft(i, i+15))
|
||||
}
|
||||
|
||||
little_endian(8, 4, H)
|
||||
}
|
||||
}
|
||||
|
||||
var tests = [
|
||||
['d41d8cd98f00b204e9800998ecf8427e', ''],
|
||||
['0cc175b9c0f1b6a831c399e269772661', 'a'],
|
||||
['900150983cd24fb0d6963f7d28e17f72', 'abc'],
|
||||
['f96b697d7cb7938d525a2f31aaf161d0', 'message digest'],
|
||||
['c3fcd3d76192e4007dfb496cca67e13b', 'abcdefghijklmnopqrstuvwxyz'],
|
||||
['d174ab98d277d9f5a5611c2c9f419d9f', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'],
|
||||
['57edf4a22be3c955ac49da2e2107b67a', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'],
|
||||
]
|
||||
|
||||
for md5,msg in tests {
|
||||
var hash = MD5(msg).md5_hex
|
||||
say "#{hash} : #{msg}"
|
||||
|
||||
if (hash != md5) {
|
||||
say "\tHowever, that is incorrect (expected: #{md5})"
|
||||
}
|
||||
}
|
||||
126
Task/MD5-Implementation/Swift/md5-implementation-1.swift
Normal file
126
Task/MD5-Implementation/Swift/md5-implementation-1.swift
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
import Foundation
|
||||
public class MD5 {
|
||||
/** specifies the per-round shift amounts */
|
||||
private let s: [UInt32] = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
|
||||
|
||||
/** binary integer part of the sines of integers (Radians) */
|
||||
private let K: [UInt32] = (0 ..< 64).map { UInt32(0x100000000 * abs(sin(Double($0 + 1)))) }
|
||||
|
||||
let a0: UInt32 = 0x67452301
|
||||
let b0: UInt32 = 0xefcdab89
|
||||
let c0: UInt32 = 0x98badcfe
|
||||
let d0: UInt32 = 0x10325476
|
||||
|
||||
private var message: NSData
|
||||
|
||||
//MARK: Public
|
||||
|
||||
public init(_ message: NSData) {
|
||||
self.message = message
|
||||
}
|
||||
|
||||
public func calculate() -> NSData? {
|
||||
var tmpMessage: NSMutableData = NSMutableData(data: message)
|
||||
let wordSize = sizeof(UInt32)
|
||||
|
||||
var aa = a0
|
||||
var bb = b0
|
||||
var cc = c0
|
||||
var dd = d0
|
||||
|
||||
// Step 1. Append Padding Bits
|
||||
tmpMessage.appendBytes([0x80]) // append one bit (Byte with one bit) to message
|
||||
|
||||
// append "0" bit until message length in bits ≡ 448 (mod 512)
|
||||
while tmpMessage.length % 64 != 56 {
|
||||
tmpMessage.appendBytes([0x00])
|
||||
}
|
||||
|
||||
// Step 2. Append Length a 64-bit representation of lengthInBits
|
||||
var lengthInBits = (message.length * 8)
|
||||
var lengthBytes = lengthInBits.bytes(64 / 8)
|
||||
tmpMessage.appendBytes(reverse(lengthBytes));
|
||||
|
||||
// Process the message in successive 512-bit chunks:
|
||||
let chunkSizeBytes = 512 / 8
|
||||
var leftMessageBytes = tmpMessage.length
|
||||
for var i = 0; i < tmpMessage.length; i = i + chunkSizeBytes, leftMessageBytes -= chunkSizeBytes {
|
||||
let chunk = tmpMessage.subdataWithRange(NSRange(location: i, length: min(chunkSizeBytes,leftMessageBytes)))
|
||||
|
||||
// break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15
|
||||
// println("wordSize \(wordSize)");
|
||||
var M:[UInt32] = [UInt32](count: 16, repeatedValue: 0)
|
||||
for x in 0..<M.count {
|
||||
var range = NSRange(location:x * wordSize, length: wordSize)
|
||||
chunk.getBytes(&M[x], range:range);
|
||||
}
|
||||
|
||||
// Initialize hash value for this chunk:
|
||||
var A:UInt32 = a0
|
||||
var B:UInt32 = b0
|
||||
var C:UInt32 = c0
|
||||
var D:UInt32 = d0
|
||||
|
||||
var dTemp:UInt32 = 0
|
||||
|
||||
// Main loop
|
||||
for j in 0...63 {
|
||||
var g = 0
|
||||
var F:UInt32 = 0
|
||||
|
||||
switch (j) {
|
||||
case 0...15:
|
||||
F = (B & C) | ((~B) & D)
|
||||
g = j
|
||||
break
|
||||
case 16...31:
|
||||
F = (D & B) | (~D & C)
|
||||
g = (5 * j + 1) % 16
|
||||
break
|
||||
case 32...47:
|
||||
F = B ^ C ^ D
|
||||
g = (3 * j + 5) % 16
|
||||
break
|
||||
case 48...63:
|
||||
F = C ^ (B | (~D))
|
||||
g = (7 * j) % 16
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
dTemp = D
|
||||
D = C
|
||||
C = B
|
||||
B = B &+ rotateLeft((A &+ F &+ K[j] &+ M[g]), s[j])
|
||||
A = dTemp
|
||||
}
|
||||
|
||||
aa = aa &+ A
|
||||
bb = bb &+ B
|
||||
cc = cc &+ C
|
||||
dd = dd &+ D
|
||||
}
|
||||
|
||||
var buf: NSMutableData = NSMutableData();
|
||||
buf.appendBytes(&aa, length: wordSize)
|
||||
buf.appendBytes(&bb, length: wordSize)
|
||||
buf.appendBytes(&cc, length: wordSize)
|
||||
buf.appendBytes(&dd, length: wordSize)
|
||||
|
||||
return buf.copy() as? NSData;
|
||||
}
|
||||
|
||||
//MARK: Class
|
||||
class func calculate(message: NSData) -> NSData?
|
||||
{
|
||||
return MD5(message).calculate();
|
||||
}
|
||||
|
||||
//MARK: Private
|
||||
private func rotateLeft(x:UInt32, _ n:UInt32) -> UInt32 {
|
||||
return (x &<< n) | (x &>> (32 - n))
|
||||
}
|
||||
}
|
||||
83
Task/MD5-Implementation/Swift/md5-implementation-2.swift
Normal file
83
Task/MD5-Implementation/Swift/md5-implementation-2.swift
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import Foundation
|
||||
|
||||
let shift : [UInt32] = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21]
|
||||
let table: [UInt32] = (0 ..< 64).map { UInt32(0x100000000 * abs(sin(Double($0 + 1)))) }
|
||||
|
||||
func md5(var message: [UInt8]) -> [UInt8] {
|
||||
var messageLenBits = UInt64(message.count) * 8
|
||||
message.append(0x80)
|
||||
while message.count % 64 != 56 {
|
||||
message.append(0)
|
||||
}
|
||||
|
||||
var lengthBytes = [UInt8](count: 8, repeatedValue: 0)
|
||||
UnsafeMutablePointer<UInt64>(lengthBytes).memory = messageLenBits.littleEndian
|
||||
message += lengthBytes
|
||||
|
||||
var a : UInt32 = 0x67452301
|
||||
var b : UInt32 = 0xEFCDAB89
|
||||
var c : UInt32 = 0x98BADCFE
|
||||
var d : UInt32 = 0x10325476
|
||||
for chunkOffset in stride(from: 0, to: message.count, by: 64) {
|
||||
let chunk = UnsafePointer<UInt32>(UnsafePointer<UInt8>(message) + chunkOffset)
|
||||
let originalA = a
|
||||
let originalB = b
|
||||
let originalC = c
|
||||
let originalD = d
|
||||
for j in 0 ..< 64 {
|
||||
var f : UInt32 = 0
|
||||
var bufferIndex = j
|
||||
let round = j >> 4
|
||||
switch round {
|
||||
case 0:
|
||||
f = (b & c) | (~b & d)
|
||||
case 1:
|
||||
f = (b & d) | (c & ~d)
|
||||
bufferIndex = (bufferIndex*5 + 1) & 0x0F
|
||||
case 2:
|
||||
f = b ^ c ^ d
|
||||
bufferIndex = (bufferIndex*3 + 5) & 0x0F
|
||||
case 3:
|
||||
f = c ^ (b | ~d)
|
||||
bufferIndex = (bufferIndex * 7) & 0x0F
|
||||
default:
|
||||
assert(false)
|
||||
}
|
||||
let sa = shift[(round<<2)|(j&3)]
|
||||
let tmp = a &+ f &+ UInt32(littleEndian: chunk[bufferIndex]) &+ table[j]
|
||||
a = d
|
||||
d = c
|
||||
c = b
|
||||
b = b &+ (tmp << sa | tmp >> (32-sa))
|
||||
}
|
||||
a = a &+ originalA
|
||||
b = b &+ originalB
|
||||
c = c &+ originalC
|
||||
d = d &+ originalD
|
||||
}
|
||||
|
||||
var result = [UInt8](count: 16, repeatedValue: 0)
|
||||
for (i, n) in enumerate([a, b, c, d]) {
|
||||
UnsafeMutablePointer<UInt32>(result)[i] = n.littleEndian
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toHexString(bytes: [UInt8]) -> String {
|
||||
return "".join(bytes.map { String(format:"%02x", $0) })
|
||||
}
|
||||
|
||||
for (hashCode, string) in [
|
||||
("d41d8cd98f00b204e9800998ecf8427e", ""),
|
||||
("0cc175b9c0f1b6a831c399e269772661", "a"),
|
||||
("900150983cd24fb0d6963f7d28e17f72", "abc"),
|
||||
("f96b697d7cb7938d525a2f31aaf161d0", "message digest"),
|
||||
("c3fcd3d76192e4007dfb496cca67e13b", "abcdefghijklmnopqrstuvwxyz"),
|
||||
("d174ab98d277d9f5a5611c2c9f419d9f",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
|
||||
("57edf4a22be3c955ac49da2e2107b67a", "12345678901234567890" +
|
||||
"123456789012345678901234567890123456789012345678901234567890")] {
|
||||
println(hashCode)
|
||||
println(toHexString(md5(Array(string.utf8))))
|
||||
println()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue