0001
0008 #if os(Linux)
0009 import Glibc
0010 #else
0011 import Foundation
0012 #endif
0013
0014
0015 extension String {
0016
0017 public func SHA1() -> String {
0018 return SHA1().reduce("") { $0 + String(format: "%02x", $1) }
0019 }
0020
0021 public func SHA1| HttpHandlers+WebSockets.swift:41 | let secWebSocketAccept = String.toBase64((secWebSocketKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").SHA1()) |
| String+SHA1.swift:18 | return SHA1().reduce("") { $0 + String(format: "%02x", $1) } |
() -> [UInt8] {
0022
0023 https://en.wikipedia.org/wiki/SHA-1
0025 var message = [UInt8](self.utf8)
0026
0027 var h0 = UInt32(littleEndian: 0x67452301)
0028 var h1 = UInt32(littleEndian: 0xEFCDAB89)
0029 var h2 = UInt32(littleEndian: 0x98BADCFE)
0030 var h3 = UInt32(littleEndian: 0x10325476)
0031 var h4 = UInt32(littleEndian: 0xC3D2E1F0)
0032
0033
0035 let ml = UInt64(message.count * 8)
0036
0037
0039 message.append(0x80)
0040
0041
0043 let padBytesCount = ( message.count + 8 ) % 64
0044
0045 message.appendContentsOf([UInt8](count: 64 - padBytesCount, repeatedValue: 0))
0046
0047
0049 var mlBigEndian = ml.bigEndian
0050 let bytePtr = withUnsafePointer(&mlBigEndian) { UnsafeBufferPointer<UInt8>(start: UnsafePointer($0), count: sizeofValue(mlBigEndian)) }
0051
0052 message.appendContentsOf(Array(bytePtr))
0053
0054
0056 for chunkStart in 0..<message.count/64 {
0057 var words = [UInt32]()
0058 let chunk = message[chunkStart*64..<chunkStart*64+64]
0059
0060
0062 for i in 0...15 {
0063 let value = chunk.withUnsafeBufferPointer({ UnsafePointer<UInt32>($0.baseAddress + (i*4)).memory })
0064 words.append(value.bigEndian)
0065 }
0066
0067
0069 for i in 16...79 {
0070 let value = words[i-3] ^ words[i-8] ^ words[i-14] ^ words[i-16]
0071 words.append(rotateLeft(value, 1))
0072 }
0073
0074
0076 var a = h0
0077 var b = h1
0078 var c = h2
0079 var d = h3
0080 var e = h4
0081
0082 for i in 0..<80 {
0083 var f = UInt32(0)
0084 var k = UInt32(0)
0085 switch i {
0086 case 0...19:
0087 f = (b & c) | ((~b) & d)
0088 k = 0x5A827999
0089 case 20...39:
0090 f = b ^ c ^ d
0091 k = 0x6ED9EBA1
0092 case 40...59:
0093 f = (b & c) | (b & d) | (c & d)
0094 k = 0x8F1BBCDC
0095 case 60...79:
0096 f = b ^ c ^ d
0097 k = 0xCA62C1D6
0098 default: break
0099 }
0100 let temp = (rotateLeft(a, 5) &+ f &+ e &+ k &+ words[i]) & 0xFFFFFFFF
0101 e = d
0102 d = c
0103 c = rotateLeft(b, 30)
0104 b = a
0105 a = temp
0106 }
0107
0108
0110 h0 = ( h0 &+ a ) & 0xFFFFFFFF
0111 h1 = ( h1 &+ b ) & 0xFFFFFFFF
0112 h2 = ( h2 &+ c ) & 0xFFFFFFFF
0113 h3 = ( h3 &+ d ) & 0xFFFFFFFF
0114 h4 = ( h4 &+ e ) & 0xFFFFFFFF
0115 }
0116
0117
0119 var result = [UInt8]()
0120
0121 let h0Big = h0.bigEndian
0122 let h1Big = h1.bigEndian
0123 let h2Big = h2.bigEndian
0124 let h3Big = h3.bigEndian
0125 let h4Big = h4.bigEndian
0126
0127 result += ([UInt8(h0Big & 0xFF), UInt8((h0Big >> 8) & 0xFF), UInt8((h0Big >> 16) & 0xFF), UInt8((h0Big >> 24) & 0xFF)]);
0128 result += ([UInt8(h1Big & 0xFF), UInt8((h1Big >> 8) & 0xFF), UInt8((h1Big >> 16) & 0xFF), UInt8((h1Big >> 24) & 0xFF)]);
0129 result += ([UInt8(h2Big & 0xFF), UInt8((h2Big >> 8) & 0xFF), UInt8((h2Big >> 16) & 0xFF), UInt8((h2Big >> 24) & 0xFF)]);
0130 result += ([UInt8(h3Big & 0xFF), UInt8((h3Big >> 8) & 0xFF), UInt8((h3Big >> 16) & 0xFF), UInt8((h3Big >> 24) & 0xFF)]);
0131 result += ([UInt8(h4Big & 0xff), UInt8((h4Big >> 8) & 0xFF), UInt8((h4Big >> 16) & 0xFF), UInt8((h4Big >> 24) & 0xFF)]);
0132
0133 return result;
0134 }
0135
0136 func rotateLeft| String+SHA1.swift:71 | words.append(rotateLeft(value, 1)) |
| String+SHA1.swift:100 | let temp = (rotateLeft(a, 5) &+ f &+ e &+ k &+ words[i]) & 0xFFFFFFFF |
| String+SHA1.swift:103 | c = rotateLeft(b, 30) |
(v: UInt32, _ n: UInt32) -> UInt32 {
0137 return ((v << n) & 0xFFFFFFFF) | (v >> (32 - n))
0138 }
0139 }
0140