[关闭]
@veightz 2015-05-15T14:27:02.000000Z 字数 19923 阅读 2264

Swift 实现 MD5 编码

Swift MD5


背景

MD5已经广泛使用在为文件传输提供一定的可靠性方面。例如,服务器预先提供一个MD5校验和,用户下载完文件以后,用MD5算法计算下载文件的MD5校验和,然后通过检查这两个校验和是否一致,就能判断下载的文件是否出错。

MD5亦有应用于部份网上赌场以保证赌博的公平性,原理是系统先在玩家下注前已生成该局的结果,将该结果的字串配合一组随机字串利用MD5 加密,将该加密字串于玩家下注前便显示给玩家,再在结果开出后将未加密的字串显示给玩家,玩家便可利用MD5工具加密验证该字串是否吻合。

例子: 在玩家下注骰宝前,赌场便先决定该局结果,假设生成的随机结果为4、5、 6大,赌场便会先利用MD5 加密“4, 5, 6”此字串并于玩家下注前告诉玩家;由于赌场是无法预计玩家会下什么注,所以便能确保赌场不能作弊;当玩家下注完毕后,赌场便告诉玩家该原始字串,即“4, 5, 6”,玩家便可利用MD5工具加密该字串是否与下注前的加密字串吻合。

该字串一般会加上一组随机字串 (Random string),以防止玩家利用碰撞 (Collision) 解密字串,但如使用超级电脑利用碰撞亦有可能从加上随机字串的加密字串中取得游戏结果。随机字串的长度与碰撞的次数成正比关系,一般网上赌场使用的随机字串是长于20字,有些网上赌场的随机字串更长达500字,以增加解密难度。

MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。

F(X,Y,Z)=(XY)(¬XZ)

G(X,Y,Z)=(XZ)(Y¬Z)

H(X,Y,Z)=XYZ

I(X,Y,Z)=Y(X¬Z)

实现

总体思路并不复杂, 大致分为三步即可。

类型定义

操作符

  1. // 循环左移
  2. infix operator <<< {
  3. associativity none
  4. precedence 140
  5. }
  6. func <<< (x: Word, n: Word) -> Word {
  7. let result: Word = (x << n) | (x >> (32 - n))
  8. return result
  9. }

数据类型及结构

  1. struct MD5 {
  2. var rawString: String
  3. var buffer: [Word]
  4. var checksum: String {}
  5. func log(word: Word) -> () {...}
  6. mutating func transform(var # string: String) -> [Word] {...}
  1. // 从字符串中取出的字符,先转为Byte(ASCII)
  2. typealias Byte = UInt8
  3. // 512位分组分为16*32位的子分组,也是非线性变换的基本单位
  4. typealias Word = UInt32
  5. // 用于存储一个512位的分组
  6. typealias Block = [Word]

初始化

  1. // 初始化变量
  2. var buffer: [Word] = [
  3. 0x67452301,
  4. 0xEFCDAB89,
  5. 0x98BADCFE,
  6. 0x10325476
  7. ]

补位预处理

  1. func encode(# string: String) -> [[Word]] {
  2. let stringLength:UInt64 = UInt64(count(string))
  3. var bytes = [Byte]()
  4. for character in string.utf8 {
  5. let byte = Byte(character)
  6. bytes.append(byte)
  7. }
  8. let charactersPaddingLength = 512 - ((stringLength * 8) + 64) % 512
  9. if charactersPaddingLength > 0 {
  10. var paddingWords = [Byte](count: Int(charactersPaddingLength / 8), repeatedValue: 0)
  11. paddingWords[0] = 0x80
  12. bytes.extend(paddingWords)
  13. }
  14. var words = [Word]()
  15. for var i = 0; i < bytes.count; i = i + 4 {
  16. let word: Word = (Word(bytes[i]) << 0)
  17. | (Word(bytes[i + 1]) << 8)
  18. | (Word(bytes[i + 2]) << 16)
  19. | (Word(bytes[i + 3]) << 24)
  20. words.append(word)
  21. }
  22. // Mark: 生成长度补位编码
  23. var lengthPaddingWords = [Word](count: 2, repeatedValue: 0)
  24. let bitsCount: UInt64 = stringLength << 3
  25. lengthPaddingWords[1] = Word(bitsCount >> 32 & 0xFFFFFFFF)
  26. lengthPaddingWords[0] = Word(bitsCount & 0xFFFFFFFF)
  27. words.extend(lengthPaddingWords)
  28. let wordsCollectionCount = words.count/16
  29. var wordsCollection = [[Word]]()
  30. for index in 0..<wordsCollectionCount {
  31. let wordsUnit = Array(words[(index*16)..<(index*16 + 16)])
  32. wordsCollection.append(wordsUnit)
  33. }
  34. return wordsCollection
  35. }

非线性变换

  1. func roundProcess(var a: Word, var b: Word, var c: Word, var d: Word,wordsArray x:[Word]) -> (Word, Word, Word, Word) {
  2. func FF(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  3. func F(# x: Word, # y: Word, # z: Word) -> Word {
  4. let result = (x & y) | ((~x) & z)
  5. return result
  6. }
  7. /*
  8. #define FF(a, b, c, d, x, s, ac) { \
  9. (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
  10. (a) = ROTATE_LEFT ((a), (s)); \
  11. (a) += (b); \
  12. }
  13. */
  14. a = Word((UInt64(a) + UInt64(F(x: b, y: c, z: d))) & 0xFFFFFFFF)
  15. a = Word((UInt64(a) + UInt64(x)) & 0xFFFFFFFF)
  16. a = Word((UInt64(a) + UInt64(ac)) & 0xFFFFFFFF)
  17. a = a <<< s
  18. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  19. return (a, b, c, d)
  20. }
  21. func GG(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  22. func G(# x: Word, # y: Word, # z: Word) -> Word {
  23. let result = (x & z) | (y & (~z))
  24. return result
  25. }
  26. /*
  27. #define GG(a, b, c, d, x, s, ac) { \
  28. (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
  29. (a) = ROTATE_LEFT ((a), (s)); \
  30. (a) += (b); \
  31. }
  32. */
  33. a = Word((UInt64(a) + UInt64(G(x: b, y: c, z: d)) + UInt64(x) + UInt64(ac)) & 0xFFFFFFFF)
  34. a = a <<< s
  35. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  36. return (a, b, c, d)
  37. }
  38. func HH(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  39. func H(# x: Word, # y: Word, # z: Word) -> Word {
  40. let result = x ^ y ^ z
  41. return result
  42. }
  43. /*
  44. #define HH(a, b, c, d, x, s, ac) { \
  45. (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
  46. (a) = ROTATE_LEFT ((a), (s)); \
  47. (a) += (b); \
  48. }
  49. */
  50. a = Word((UInt64(a) + UInt64(H(x: b, y: c, z: d)) + UInt64(x) + UInt64(ac)) & 0xFFFFFFFF)
  51. a = a <<< s
  52. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  53. return (a, b, c, d)
  54. }
  55. func II(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  56. func I(# x: Word, # y: Word, # z: Word) -> Word {
  57. let result = y ^ (x | (~z))
  58. return result
  59. }
  60. /*
  61. #define II(a, b, c, d, x, s, ac) { \
  62. (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
  63. (a) = ROTATE_LEFT ((a), (s)); \
  64. (a) += (b); \
  65. }
  66. */
  67. a = Word((UInt64(a) + UInt64(I(x: b, y: c, z: d)) + UInt64(x) + UInt64(ac)) & 0xFFFFFFFF)
  68. a = a <<< s
  69. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  70. return (a, b, c, d)
  71. }
  72. let aa = a
  73. let bb = b
  74. let cc = c
  75. let dd = d
  76. /* Round 1. */
  77. /* Let [abcd k s i] denote the operation
  78. a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
  79. /* Do the following 16 operations. */
  80. /*
  81. [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
  82. [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
  83. [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
  84. [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
  85. */
  86. (a, b, c, d) = FF(a, b, c, d, x: x[ 0], s: S11, ac: 0xd76aa478); /* 1 */
  87. (d, a, b, c) = FF(d, a, b, c, x: x[ 1], s: S12, ac: 0xe8c7b756); /* 2 */
  88. (c, d, a, b) = FF(c, d, a, b, x: x[ 2], s: S13, ac: 0x242070db); /* 3 */
  89. (b, c, d, a) = FF(b, c, d, a, x: x[ 3], s: S14, ac: 0xc1bdceee); /* 4 */
  90. (a, b, c, d) = FF(a, b, c, d, x: x[ 4], s: S11, ac: 0xf57c0faf); /* 5 */
  91. (d, a, b, c) = FF(d, a, b, c, x: x[ 5], s: S12, ac: 0x4787c62a); /* 6 */
  92. (c, d, a, b) = FF(c, d, a, b, x: x[ 6], s: S13, ac: 0xa8304613); /* 7 */
  93. (b, c, d, a) = FF(b, c, d, a, x: x[ 7], s: S14, ac: 0xfd469501); /* 8 */
  94. (a, b, c, d) = FF(a, b, c, d, x: x[ 8], s: S11, ac: 0x698098d8); /* 9 */
  95. (d, a, b, c) = FF(d, a, b, c, x: x[ 9], s: S12, ac: 0x8b44f7af); /* 10 */
  96. (c, d, a, b) = FF(c, d, a, b, x: x[10], s: S13, ac: 0xffff5bb1); /* 11 */
  97. (b, c, d, a) = FF(b, c, d, a, x: x[11], s: S14, ac: 0x895cd7be); /* 12 */
  98. (a, b, c, d) = FF(a, b, c, d, x: x[12], s: S11, ac: 0x6b901122); /* 13 */
  99. (d, a, b, c) = FF(d, a, b, c, x: x[13], s: S12, ac: 0xfd987193); /* 14 */
  100. (c, d, a, b) = FF(c, d, a, b, x: x[14], s: S13, ac: 0xa679438e); /* 15 */
  101. (b, c, d, a) = FF(b, c, d, a, x: x[15], s: S14, ac: 0x49b40821); /* 16 */
  102. /* Round 2. */
  103. /* Let [abcd k s i] denote the operation
  104. a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
  105. /* Do the following 16 operations. */
  106. /*
  107. [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
  108. [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
  109. [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
  110. [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
  111. */
  112. (a, b, c, d) = GG(a, b, c, d, x: x[ 1], s: S21, ac: 0xf61e2562); /* 17 */
  113. (d, a, b, c) = GG(d, a, b, c, x: x[ 6], s: S22, ac: 0xc040b340); /* 18 */
  114. (c, d, a, b) = GG(c, d, a, b, x: x[11], s: S23, ac: 0x265e5a51); /* 19 */
  115. (b, c, d, a) = GG(b, c, d, a, x: x[ 0], s: S24, ac: 0xe9b6c7aa); /* 20 */
  116. (a, b, c, d) = GG(a, b, c, d, x: x[ 5], s: S21, ac: 0xd62f105d); /* 21 */
  117. (d, a, b, c) = GG(d, a, b, c, x: x[10], s: S22, ac: 0x2441453); /* 22 */
  118. (c, d, a, b) = GG(c, d, a, b, x: x[15], s: S23, ac: 0xd8a1e681); /* 23 */
  119. (b, c, d, a) = GG(b, c, d, a, x: x[ 4], s: S24, ac: 0xe7d3fbc8); /* 24 */
  120. (a, b, c, d) = GG(a, b, c, d, x: x[ 9], s: S21, ac: 0x21e1cde6); /* 25 */
  121. (d, a, b, c) = GG(d, a, b, c, x: x[14], s: S22, ac: 0xc33707d6); /* 26 */
  122. (c, d, a, b) = GG(c, d, a, b, x: x[ 3], s: S23, ac: 0xf4d50d87); /* 27 */
  123. (b, c, d, a) = GG(b, c, d, a, x: x[ 8], s: S24, ac: 0x455a14ed); /* 28 */
  124. (a, b, c, d) = GG(a, b, c, d, x: x[13], s: S21, ac: 0xa9e3e905); /* 29 */
  125. (d, a, b, c) = GG(d, a, b, c, x: x[ 2], s: S22, ac: 0xfcefa3f8); /* 30 */
  126. (c, d, a, b) = GG(c, d, a, b, x: x[ 7], s: S23, ac: 0x676f02d9); /* 31 */
  127. (b, c, d, a) = GG(b, c, d, a, x: x[12], s: S24, ac: 0x8d2a4c8a); /* 32 */
  128. /* Round 3. */
  129. /* Let [abcd k s t] denote the operation
  130. a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
  131. /* Do the following 16 operations. */
  132. /*
  133. [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
  134. [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
  135. [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
  136. [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
  137. */
  138. (a, b, c, d) = HH(a, b, c, d, x: x[ 5], s: S31, ac: 0xfffa3942); /* 33 */
  139. (d, a, b, c) = HH(d, a, b, c, x: x[ 8], s: S32, ac: 0x8771f681); /* 34 */
  140. (c, d, a, b) = HH(c, d, a, b, x: x[11], s: S33, ac: 0x6d9d6122); /* 35 */
  141. (b, c, d, a) = HH(b, c, d, a, x: x[14], s: S34, ac: 0xfde5380c); /* 36 */
  142. (a, b, c, d) = HH(a, b, c, d, x: x[ 1], s: S31, ac: 0xa4beea44); /* 37 */
  143. (d, a, b, c) = HH(d, a, b, c, x: x[ 4], s: S32, ac: 0x4bdecfa9); /* 38 */
  144. (c, d, a, b) = HH(c, d, a, b, x: x[ 7], s: S33, ac: 0xf6bb4b60); /* 39 */
  145. (b, c, d, a) = HH(b, c, d, a, x: x[10], s: S34, ac: 0xbebfbc70); /* 40 */
  146. (a, b, c, d) = HH(a, b, c, d, x: x[13], s: S31, ac: 0x289b7ec6); /* 41 */
  147. (d, a, b, c) = HH(d, a, b, c, x: x[ 0], s: S32, ac: 0xeaa127fa); /* 42 */
  148. (c, d, a, b) = HH(c, d, a, b, x: x[ 3], s: S33, ac: 0xd4ef3085); /* 43 */
  149. (b, c, d, a) = HH(b, c, d, a, x: x[ 6], s: S34, ac: 0x4881d05); /* 44 */
  150. (a, b, c, d) = HH(a, b, c, d, x: x[ 9], s: S31, ac: 0xd9d4d039); /* 45 */
  151. (d, a, b, c) = HH(d, a, b, c, x: x[12], s: S32, ac: 0xe6db99e5); /* 46 */
  152. (c, d, a, b) = HH(c, d, a, b, x: x[15], s: S33, ac: 0x1fa27cf8); /* 47 */
  153. (b, c, d, a) = HH(b, c, d, a, x: x[ 2], s: S34, ac: 0xc4ac5665); /* 48 */
  154. /* Round 4. */
  155. /* Let [abcd k s t] denote the operation
  156. a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
  157. /* Do the following 16 operations. */
  158. /*
  159. [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
  160. [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
  161. [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
  162. [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
  163. */
  164. (a, b, c, d) = II(a, b, c, d, x: x[ 0], s: S41, ac: 0xf4292244); /* 49 */
  165. (d, a, b, c) = II(d, a, b, c, x: x[ 7], s: S42, ac: 0x432aff97); /* 50 */
  166. (c, d, a, b) = II(c, d, a, b, x: x[14], s: S43, ac: 0xab9423a7); /* 51 */
  167. (b, c, d, a) = II(b, c, d, a, x: x[ 5], s: S44, ac: 0xfc93a039); /* 52 */
  168. (a, b, c, d) = II(a, b, c, d, x: x[12], s: S41, ac: 0x655b59c3); /* 53 */
  169. (d, a, b, c) = II(d, a, b, c, x: x[ 3], s: S42, ac: 0x8f0ccc92); /* 54 */
  170. (c, d, a, b) = II(c, d, a, b, x: x[10], s: S43, ac: 0xffeff47d); /* 55 */
  171. (b, c, d, a) = II(b, c, d, a, x: x[ 1], s: S44, ac: 0x85845dd1); /* 56 */
  172. (a, b, c, d) = II(a, b, c, d, x: x[ 8], s: S41, ac: 0x6fa87e4f); /* 57 */
  173. (d, a, b, c) = II(d, a, b, c, x: x[15], s: S42, ac: 0xfe2ce6e0); /* 58 */
  174. (c, d, a, b) = II(c, d, a, b, x: x[ 6], s: S43, ac: 0xa3014314); /* 59 */
  175. (b, c, d, a) = II(b, c, d, a, x: x[13], s: S44, ac: 0x4e0811a1); /* 60 */
  176. (a, b, c, d) = II(a, b, c, d, x: x[ 4], s: S41, ac: 0xf7537e82); /* 61 */
  177. (d, a, b, c) = II(d, a, b, c, x: x[11], s: S42, ac: 0xbd3af235); /* 62 */
  178. (c, d, a, b) = II(c, d, a, b, x: x[ 2], s: S43, ac: 0x2ad7d2bb); /* 63 */
  179. (b, c, d, a) = II(b, c, d, a, x: x[ 9], s: S44, ac: 0xeb86d391); /* 64 */
  180. /* Then perform the following additions. (That is increment each
  181. of the four registers by the value it had before this block
  182. was started.) */
  183. /*
  184. A = A + AA
  185. B = B + BB
  186. C = C + CC
  187. D = D + DD
  188. */
  189. a = Word((UInt64(a) + UInt64(aa)) & 0xFFFFFFFF)
  190. b = Word((UInt64(b) + UInt64(bb)) & 0xFFFFFFFF)
  191. c = Word((UInt64(c) + UInt64(cc)) & 0xFFFFFFFF)
  192. d = Word((UInt64(d) + UInt64(dd)) & 0xFFFFFFFF)
  193. return (a, b, c, d)
  194. }

验证

实验代码

  1. //
  2. // main.swift
  3. // MD5-Swift
  4. //
  5. // Created by Veight Zhou on 5/12/15.
  6. // Copyright (c) 2015 Veight Zhou. All rights reserved.
  7. //
  8. import Foundation
  9. // 定义类型
  10. typealias Byte = UInt8
  11. typealias Word = UInt32
  12. typealias Block = [Word]
  13. /**
  14. We define a rotate left operator <<<
  15. */
  16. infix operator <<< {
  17. associativity none
  18. precedence 140
  19. }
  20. func <<< (x: Word, n: Word) -> Word {
  21. let result: Word = (x << n) | (x >> (32 - n))
  22. return result
  23. }
  24. struct MD5 {
  25. var rawString: String = "" {
  26. didSet {
  27. buffer = [
  28. 0x67452301,
  29. 0xEFCDAB89,
  30. 0x98BADCFE,
  31. 0x10325476
  32. ]
  33. transform(string: rawString)
  34. }
  35. }
  36. var buffer: [Word] = [
  37. 0x67452301,
  38. 0xEFCDAB89,
  39. 0x98BADCFE,
  40. 0x10325476
  41. ]
  42. var checksum: String {
  43. get {
  44. return decode(words: buffer)
  45. }
  46. }
  47. func log(word: Word) -> () {
  48. var binaryString = ""
  49. for index in 0...31 {
  50. binaryString = String(word >> Word(index) & 0x1) + binaryString
  51. if index % 8 == 7 {
  52. binaryString = " " + binaryString
  53. }
  54. }
  55. binaryString += " -> \(word)"
  56. }
  57. mutating func transform(var # string: String) -> () {
  58. let S11: Word = 7
  59. let S12: Word = 12
  60. let S13: Word = 17
  61. let S14: Word = 22
  62. let S21: Word = 5
  63. let S22: Word = 9
  64. let S23: Word = 14
  65. let S24: Word = 20
  66. let S31: Word = 4
  67. let S32: Word = 11
  68. let S33: Word = 16
  69. let S34: Word = 23
  70. let S41: Word = 6
  71. let S42: Word = 10
  72. let S43: Word = 15
  73. let S44: Word = 21
  74. /**
  75. 对输入的文本进行编码, 返回一个编码后的数组。数据中的每个元素都是容量为16的Word数组, 即16*32位的子分组。
  76. :param: string 需要编码的文本
  77. :returns: 每个元素都是容量为16的Word数组
  78. */
  79. func encode(# string: String) -> [[Word]] {
  80. let stringLength:UInt64 = UInt64(count(string))
  81. var bytes = [Byte]()
  82. for character in string.utf8 {
  83. let byte = Byte(character)
  84. bytes.append(byte)
  85. }
  86. let charactersPaddingLength = 512 - ((stringLength * 8) + 64) % 512
  87. if charactersPaddingLength > 0 {
  88. var paddingWords = [Byte](count: Int(charactersPaddingLength / 8), repeatedValue: 0)
  89. paddingWords[0] = 0x80
  90. bytes.extend(paddingWords)
  91. }
  92. var words = [Word]()
  93. for var i = 0; i < bytes.count; i = i + 4 {
  94. let word: Word = (Word(bytes[i]) << 0)
  95. | (Word(bytes[i + 1]) << 8)
  96. | (Word(bytes[i + 2]) << 16)
  97. | (Word(bytes[i + 3]) << 24)
  98. words.append(word)
  99. }
  100. // Mark: 生成长度补位编码
  101. var lengthPaddingWords = [Word](count: 2, repeatedValue: 0)
  102. let bitsCount: UInt64 = stringLength << 3
  103. lengthPaddingWords[1] = Word(bitsCount >> 32 & 0xFFFFFFFF)
  104. lengthPaddingWords[0] = Word(bitsCount & 0xFFFFFFFF)
  105. words.extend(lengthPaddingWords)
  106. let wordsCollectionCount = words.count/16
  107. var wordsCollection = [[Word]]()
  108. for index in 0..<wordsCollectionCount {
  109. let wordsUnit = Array(words[(index*16)..<(index*16 + 16)])
  110. wordsCollection.append(wordsUnit)
  111. }
  112. return wordsCollection
  113. }
  114. func roundProcess(var a: Word, var b: Word, var c: Word, var d: Word,wordsArray x:[Word]) -> (Word, Word, Word, Word) {
  115. func FF(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  116. func F(# x: Word, # y: Word, # z: Word) -> Word {
  117. let result = (x & y) | ((~x) & z)
  118. return result
  119. }
  120. /*
  121. #define FF(a, b, c, d, x, s, ac) { \
  122. (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
  123. (a) = ROTATE_LEFT ((a), (s)); \
  124. (a) += (b); \
  125. }
  126. */
  127. a = Word((UInt64(a) + UInt64(F(x: b, y: c, z: d))) & 0xFFFFFFFF)
  128. a = Word((UInt64(a) + UInt64(x)) & 0xFFFFFFFF)
  129. a = Word((UInt64(a) + UInt64(ac)) & 0xFFFFFFFF)
  130. a = a <<< s
  131. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  132. return (a, b, c, d)
  133. }
  134. func GG(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  135. func G(# x: Word, # y: Word, # z: Word) -> Word {
  136. let result = (x & z) | (y & (~z))
  137. return result
  138. }
  139. /*
  140. #define GG(a, b, c, d, x, s, ac) { \
  141. (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
  142. (a) = ROTATE_LEFT ((a), (s)); \
  143. (a) += (b); \
  144. }
  145. */
  146. a = Word((UInt64(a) + UInt64(G(x: b, y: c, z: d)) + UInt64(x) + UInt64(ac)) & 0xFFFFFFFF)
  147. a = a <<< s
  148. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  149. return (a, b, c, d)
  150. }
  151. func HH(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  152. func H(# x: Word, # y: Word, # z: Word) -> Word {
  153. let result = x ^ y ^ z
  154. return result
  155. }
  156. /*
  157. #define HH(a, b, c, d, x, s, ac) { \
  158. (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
  159. (a) = ROTATE_LEFT ((a), (s)); \
  160. (a) += (b); \
  161. }
  162. */
  163. a = Word((UInt64(a) + UInt64(H(x: b, y: c, z: d)) + UInt64(x) + UInt64(ac)) & 0xFFFFFFFF)
  164. a = a <<< s
  165. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  166. return (a, b, c, d)
  167. }
  168. func II(var a: Word, var b: Word, var c: Word, var d: Word, # x: Word, # s: Word, # ac:Word) -> (Word, Word, Word, Word) {
  169. func I(# x: Word, # y: Word, # z: Word) -> Word {
  170. let result = y ^ (x | (~z))
  171. return result
  172. }
  173. /*
  174. #define II(a, b, c, d, x, s, ac) { \
  175. (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
  176. (a) = ROTATE_LEFT ((a), (s)); \
  177. (a) += (b); \
  178. }
  179. */
  180. a = Word((UInt64(a) + UInt64(I(x: b, y: c, z: d)) + UInt64(x) + UInt64(ac)) & 0xFFFFFFFF)
  181. a = a <<< s
  182. a = Word((UInt64(a) + UInt64(b)) & 0xFFFFFFFF)
  183. return (a, b, c, d)
  184. }
  185. let aa = a
  186. let bb = b
  187. let cc = c
  188. let dd = d
  189. /* Round 1. */
  190. /* Let [abcd k s i] denote the operation
  191. a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
  192. /* Do the following 16 operations. */
  193. /*
  194. [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
  195. [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
  196. [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
  197. [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
  198. */
  199. (a, b, c, d) = FF(a, b, c, d, x: x[ 0], s: S11, ac: 0xd76aa478); /* 1 */
  200. (d, a, b, c) = FF(d, a, b, c, x: x[ 1], s: S12, ac: 0xe8c7b756); /* 2 */
  201. (c, d, a, b) = FF(c, d, a, b, x: x[ 2], s: S13, ac: 0x242070db); /* 3 */
  202. (b, c, d, a) = FF(b, c, d, a, x: x[ 3], s: S14, ac: 0xc1bdceee); /* 4 */
  203. (a, b, c, d) = FF(a, b, c, d, x: x[ 4], s: S11, ac: 0xf57c0faf); /* 5 */
  204. (d, a, b, c) = FF(d, a, b, c, x: x[ 5], s: S12, ac: 0x4787c62a); /* 6 */
  205. (c, d, a, b) = FF(c, d, a, b, x: x[ 6], s: S13, ac: 0xa8304613); /* 7 */
  206. (b, c, d, a) = FF(b, c, d, a, x: x[ 7], s: S14, ac: 0xfd469501); /* 8 */
  207. (a, b, c, d) = FF(a, b, c, d, x: x[ 8], s: S11, ac: 0x698098d8); /* 9 */
  208. (d, a, b, c) = FF(d, a, b, c, x: x[ 9], s: S12, ac: 0x8b44f7af); /* 10 */
  209. (c, d, a, b) = FF(c, d, a, b, x: x[10], s: S13, ac: 0xffff5bb1); /* 11 */
  210. (b, c, d, a) = FF(b, c, d, a, x: x[11], s: S14, ac: 0x895cd7be); /* 12 */
  211. (a, b, c, d) = FF(a, b, c, d, x: x[12], s: S11, ac: 0x6b901122); /* 13 */
  212. (d, a, b, c) = FF(d, a, b, c, x: x[13], s: S12, ac: 0xfd987193); /* 14 */
  213. (c, d, a, b) = FF(c, d, a, b, x: x[14], s: S13, ac: 0xa679438e); /* 15 */
  214. (b, c, d, a) = FF(b, c, d, a, x: x[15], s: S14, ac: 0x49b40821); /* 16 */
  215. /* Round 2. */
  216. /* Let [abcd k s i] denote the operation
  217. a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
  218. /* Do the following 16 operations. */
  219. /*
  220. [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
  221. [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
  222. [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
  223. [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
  224. */
  225. (a, b, c, d) = GG(a, b, c, d, x: x[ 1], s: S21, ac: 0xf61e2562); /* 17 */
  226. (d, a, b, c) = GG(d, a, b, c, x: x[ 6], s: S22, ac: 0xc040b340); /* 18 */
  227. (c, d, a, b) = GG(c, d, a, b, x: x[11], s: S23, ac: 0x265e5a51); /* 19 */
  228. (b, c, d, a) = GG(b, c, d, a, x: x[ 0], s: S24, ac: 0xe9b6c7aa); /* 20 */
  229. (a, b, c, d) = GG(a, b, c, d, x: x[ 5], s: S21, ac: 0xd62f105d); /* 21 */
  230. (d, a, b, c) = GG(d, a, b, c, x: x[10], s: S22, ac: 0x2441453); /* 22 */
  231. (c, d, a, b) = GG(c, d, a, b, x: x[15], s: S23, ac: 0xd8a1e681); /* 23 */
  232. (b, c, d, a) = GG(b, c, d, a, x: x[ 4], s: S24, ac: 0xe7d3fbc8); /* 24 */
  233. (a, b, c, d) = GG(a, b, c, d, x: x[ 9], s: S21, ac: 0x21e1cde6); /* 25 */
  234. (d, a, b, c) = GG(d, a, b, c, x: x[14], s: S22, ac: 0xc33707d6); /* 26 */
  235. (c, d, a, b) = GG(c, d, a, b, x: x[ 3], s: S23, ac: 0xf4d50d87); /* 27 */
  236. (b, c, d, a) = GG(b, c, d, a, x: x[ 8], s: S24, ac: 0x455a14ed); /* 28 */
  237. (a, b, c, d) = GG(a, b, c, d, x: x[13], s: S21, ac: 0xa9e3e905); /* 29 */
  238. (d, a, b, c) = GG(d, a, b, c, x: x[ 2], s: S22, ac: 0xfcefa3f8); /* 30 */
  239. (c, d, a, b) = GG(c, d, a, b, x: x[ 7], s: S23, ac: 0x676f02d9); /* 31 */
  240. (b, c, d, a) = GG(b, c, d, a, x: x[12], s: S24, ac: 0x8d2a4c8a); /* 32 */
  241. /* Round 3. */
  242. /* Let [abcd k s t] denote the operation
  243. a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
  244. /* Do the following 16 operations. */
  245. /*
  246. [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
  247. [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
  248. [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
  249. [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
  250. */
  251. (a, b, c, d) = HH(a, b, c, d, x: x[ 5], s: S31, ac: 0xfffa3942); /* 33 */
  252. (d, a, b, c) = HH(d, a, b, c, x: x[ 8], s: S32, ac: 0x8771f681); /* 34 */
  253. (c, d, a, b) = HH(c, d, a, b, x: x[11], s: S33, ac: 0x6d9d6122); /* 35 */
  254. (b, c, d, a) = HH(b, c, d, a, x: x[14], s: S34, ac: 0xfde5380c); /* 36 */
  255. (a, b, c, d) = HH(a, b, c, d, x: x[ 1], s: S31, ac: 0xa4beea44); /* 37 */
  256. (d, a, b, c) = HH(d, a, b, c, x: x[ 4], s: S32, ac: 0x4bdecfa9); /* 38 */
  257. (c, d, a, b) = HH(c, d, a, b, x: x[ 7], s: S33, ac: 0xf6bb4b60); /* 39 */
  258. (b, c, d, a) = HH(b, c, d, a, x: x[10], s: S34, ac: 0xbebfbc70); /* 40 */
  259. (a, b, c, d) = HH(a, b, c, d, x: x[13], s: S31, ac: 0x289b7ec6); /* 41 */
  260. (d, a, b, c) = HH(d, a, b, c, x: x[ 0], s: S32, ac: 0xeaa127fa); /* 42 */
  261. (c, d, a, b) = HH(c, d, a, b, x: x[ 3], s: S33, ac: 0xd4ef3085); /* 43 */
  262. (b, c, d, a) = HH(b, c, d, a, x: x[ 6], s: S34, ac: 0x4881d05); /* 44 */
  263. (a, b, c, d) = HH(a, b, c, d, x: x[ 9], s: S31, ac: 0xd9d4d039); /* 45 */
  264. (d, a, b, c) = HH(d, a, b, c, x: x[12], s: S32, ac: 0xe6db99e5); /* 46 */
  265. (c, d, a, b) = HH(c, d, a, b, x: x[15], s: S33, ac: 0x1fa27cf8); /* 47 */
  266. (b, c, d, a) = HH(b, c, d, a, x: x[ 2], s: S34, ac: 0xc4ac5665); /* 48 */
  267. /* Round 4. */
  268. /* Let [abcd k s t] denote the operation
  269. a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
  270. /* Do the following 16 operations. */
  271. /*
  272. [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
  273. [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
  274. [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
  275. [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
  276. */
  277. (a, b, c, d) = II(a, b, c, d, x: x[ 0], s: S41, ac: 0xf4292244); /* 49 */
  278. (d, a, b, c) = II(d, a, b, c, x: x[ 7], s: S42, ac: 0x432aff97); /* 50 */
  279. (c, d, a, b) = II(c, d, a, b, x: x[14], s: S43, ac: 0xab9423a7); /* 51 */
  280. (b, c, d, a) = II(b, c, d, a, x: x[ 5], s: S44, ac: 0xfc93a039); /* 52 */
  281. (a, b, c, d) = II(a, b, c, d, x: x[12], s: S41, ac: 0x655b59c3); /* 53 */
  282. (d, a, b, c) = II(d, a, b, c, x: x[ 3], s: S42, ac: 0x8f0ccc92); /* 54 */
  283. (c, d, a, b) = II(c, d, a, b, x: x[10], s: S43, ac: 0xffeff47d); /* 55 */
  284. (b, c, d, a) = II(b, c, d, a, x: x[ 1], s: S44, ac: 0x85845dd1); /* 56 */
  285. (a, b, c, d) = II(a, b, c, d, x: x[ 8], s: S41, ac: 0x6fa87e4f); /* 57 */
  286. (d, a, b, c) = II(d, a, b, c, x: x[15], s: S42, ac: 0xfe2ce6e0); /* 58 */
  287. (c, d, a, b) = II(c, d, a, b, x: x[ 6], s: S43, ac: 0xa3014314); /* 59 */
  288. (b, c, d, a) = II(b, c, d, a, x: x[13], s: S44, ac: 0x4e0811a1); /* 60 */
  289. (a, b, c, d) = II(a, b, c, d, x: x[ 4], s: S41, ac: 0xf7537e82); /* 61 */
  290. (d, a, b, c) = II(d, a, b, c, x: x[11], s: S42, ac: 0xbd3af235); /* 62 */
  291. (c, d, a, b) = II(c, d, a, b, x: x[ 2], s: S43, ac: 0x2ad7d2bb); /* 63 */
  292. (b, c, d, a) = II(b, c, d, a, x: x[ 9], s: S44, ac: 0xeb86d391); /* 64 */
  293. /* Then perform the following additions. (That is increment each
  294. of the four registers by the value it had before this block
  295. was started.) */
  296. /*
  297. A = A + AA
  298. B = B + BB
  299. C = C + CC
  300. D = D + DD
  301. */
  302. a = Word((UInt64(a) + UInt64(aa)) & 0xFFFFFFFF)
  303. b = Word((UInt64(b) + UInt64(bb)) & 0xFFFFFFFF)
  304. c = Word((UInt64(c) + UInt64(cc)) & 0xFFFFFFFF)
  305. d = Word((UInt64(d) + UInt64(dd)) & 0xFFFFFFFF)
  306. return (a, b, c, d)
  307. }
  308. let wordsArray = encode(string: rawString)
  309. var tempBuffer = (a: buffer[0], b: buffer[1], c: buffer[2], d: buffer[3])
  310. for words in wordsArray {
  311. tempBuffer = roundProcess(tempBuffer.a, tempBuffer.b, tempBuffer.c, tempBuffer.d, wordsArray: words)
  312. }
  313. buffer = [tempBuffer.a, tempBuffer.b, tempBuffer.c, tempBuffer.d]
  314. let string = decode(words: buffer)
  315. }
  316. private func decode(# words: [Word]) -> String {
  317. let easyMap: [UInt32: Character] = [
  318. 0x00: "0", 0x01: "1", 0x02: "2", 0x03: "3", 0x04: "4", 0x05: "5", 0x06: "6", 0x07: "7",
  319. 0x08: "8", 0x09: "9", 0x0A: "a", 0x0B: "b", 0x0C: "c", 0x0D: "d", 0x0E: "e", 0x0F: "f"
  320. ]
  321. var string = ""
  322. for i in 0..<(words.count) {
  323. let word = words[i]
  324. for j in 0...3 {
  325. let s0 = easyMap[(UInt32(word) >> UInt32(j * 8 + 4)) & 0xF]!
  326. let s1 = easyMap[(UInt32(word) >> UInt32(j * 8)) & 0xF]!
  327. string.append(s0)
  328. string.append(s1)
  329. }
  330. }
  331. return string
  332. }
  333. }
  334. var md5 = MD5()
  335. md5.rawString = "abc"
  336. println("\(md5.rawString) ==> \(md5.checksum)")
  337. md5.rawString = "a"
  338. println("\(md5.rawString) ==> \(md5.checksum)")
  339. md5.rawString = "message digest"
  340. println("\(md5.rawString) ==> \(md5.checksum)")
  341. md5.rawString = "abcdefghijklmnopqrstuvwxyz"
  342. println("\(md5.rawString) ==> \(md5.checksum)")
  343. md5.rawString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
  344. println("\(md5.rawString) ==> \(md5.checksum)")
  345. md5.rawString = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
  346. println("\(md5.rawString) ==> \(md5.checksum)")

输出结果

  1. abc ==> 900150983cd24fb0d6963f7d28e17f72
  2. a ==> 0cc175b9c0f1b6a831c399e269772661
  3. message digest ==> f96b697d7cb7938d525a2f31aaf161d0
  4. abcdefghijklmnopqrstuvwxyz ==> c3fcd3d76192e4007dfb496cca67e13b
  5. ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ==> d174ab98d277d9f5a5611c2c9f419d9f
  6. 12345678901234567890123456789012345678901234567890123456789012345678901234567890 ==> 57edf4a22be3c955ac49da2e2107b67a
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注