0001    //
0002    //  String+SHA1.swift
0003    //  Swifter
0004    //
0005    //  Copyright 2014-2016 Damian Kołakowski. All rights reserved.
0006    //
0007    
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 // Alghorithm from: https://en.wikipedia.org/wiki/SHA-1 0024 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 // ml = message length in bits (always a multiple of the number of bits in a character). 0034 0035 let ml = UInt64(message.count * 8) 0036 0037 // append the bit '1' to the message e.g. by adding 0x80 if message length is a multiple of 8 bits. 0038 0039 message.append(0x80) 0040 0041 // append 0 ≤ k < 512 bits '0', such that the resulting message length in bits is congruent to −64 ≡ 448 (mod 512) 0042 0043 let padBytesCount = ( message.count + 8 ) % 64 0044 0045 message.appendContentsOf([UInt8](count: 64 - padBytesCount, repeatedValue: 0)) 0046 0047 // append ml, in a 64-bit big-endian integer. Thus, the total length is a multiple of 512 bits. 0048 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 // Process the message in successive 512-bit chunks ( 64 bytes chunks ): 0055 0056 for chunkStart in 0..<message.count/64 { 0057 var words = [UInt32]() 0058 let chunk = message[chunkStart*64..<chunkStart*64+64] 0059 0060 // break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15 0061 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 // Extend the sixteen 32-bit words into eighty 32-bit words: 0068 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 // Initialize hash value for this chunk: 0075 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 // Add this chunk's hash to result so far: 0109 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 // Produce the final hash value (big-endian) as a 160 bit number: 0118 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