UNPKG

5.12 kBPlain TextView Raw
1import {rstr2hex, rstr2b64, rstr2any, utf8Encode, binb2rstr, rstr2binb, safe_add, bit_rol} from "./utils";
2
3/**
4 * Copy from https://github.com/h2non/jshashes/blob/master/hashes.js
5 */
6
7const SHA1 = function SHA1 (options?) {
8 /**
9 * Private config properties. You may need to tweak these to be compatible with
10 * the server-side, but the defaults work in most cases.
11 * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
12 */
13 var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
14 b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
15 utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
16
17 // public methods
18 this.hex = function (s) {
19 return rstr2hex(rstr(s, utf8), hexcase);
20 };
21 this.b64 = function (s) {
22 return rstr2b64(rstr(s, utf8), b64pad);
23 };
24 this.any = function (s, e) {
25 return rstr2any(rstr(s, utf8), e);
26 };
27 this.raw = function (s) {
28 return rstr(s, utf8);
29 };
30 this.hex_hmac = function (k, d) {
31 return rstr2hex(rstr_hmac(k, d));
32 };
33 this.b64_hmac = function (k, d) {
34 return rstr2b64(rstr_hmac(k, d), b64pad);
35 };
36 this.any_hmac = function (k, d, e) {
37 return rstr2any(rstr_hmac(k, d), e);
38 };
39 /**
40 * Perform a simple self-test to see if the VM is working
41 * @return {String} Hexadecimal hash sample
42 * @public
43 */
44 /*this.vm_test = function () {
45 return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
46 };*/
47 /**
48 * @description Enable/disable uppercase hexadecimal returned string
49 * @param {boolean} a
50 * @return {Object} this
51 * @public
52 */
53 this.setUpperCase = function (a) {
54 if (typeof a === 'boolean') {
55 hexcase = a;
56 }
57 return this;
58 };
59 /**
60 * @description Defines a base64 pad string
61 * @param {string} Pad
62 * @return {Object} this
63 * @public
64 */
65 this.setPad = function (Pad) {
66 b64pad = Pad || b64pad;
67 return this;
68 };
69 /**
70 * @description Defines a base64 pad string
71 * @param {boolean} a
72 * @return {Object} this
73 * @public
74 */
75 this.setUTF8 = function (a) {
76 if (typeof a === 'boolean') {
77 utf8 = a;
78 }
79 return this;
80 };
81
82 // private methods
83
84 /**
85 * Calculate the SHA-1 of an array of big-endian words, and a bit length
86 */
87 function binb(x, len) {
88 var i, j, t, olda, oldb, oldc, oldd, olde,
89 w = Array(80),
90 a = 1732584193,
91 b = -271733879,
92 c = -1732584194,
93 d = 271733878,
94 e = -1009589776;
95
96 /* append padding */
97 x[len >> 5] |= 0x80 << (24 - len % 32);
98 x[((len + 64 >> 9) << 4) + 15] = len;
99
100 for (i = 0; i < x.length; i += 16) {
101 olda = a;
102 oldb = b;
103 oldc = c;
104 oldd = d;
105 olde = e;
106
107 for (j = 0; j < 80; j += 1) {
108 if (j < 16) {
109 w[j] = x[i + j];
110 } else {
111 w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
112 }
113 t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
114 safe_add(safe_add(e, w[j]), sha1_kt(j)));
115 e = d;
116 d = c;
117 c = bit_rol(b, 30);
118 b = a;
119 a = t;
120 }
121
122 a = safe_add(a, olda);
123 b = safe_add(b, oldb);
124 c = safe_add(c, oldc);
125 d = safe_add(d, oldd);
126 e = safe_add(e, olde);
127 }
128 return Array(a, b, c, d, e);
129 }
130
131 /**
132 * Calculate the SHA-512 of a raw string
133 */
134 function rstr(s, utf8?) {
135 s = (utf8) ? utf8Encode(s) : s;
136 return binb2rstr(binb(rstr2binb(s), s.length * 8));
137 }
138
139 /**
140 * Calculate the HMAC-SHA1 of a key and some data (raw strings)
141 */
142 function rstr_hmac(key, data) {
143 var bkey, ipad, opad, i, hash;
144 key = (utf8) ? utf8Encode(key) : key;
145 data = (utf8) ? utf8Encode(data) : data;
146 bkey = rstr2binb(key);
147
148 if (bkey.length > 16) {
149 bkey = binb(bkey, key.length * 8);
150 }
151 ipad = Array(16), opad = Array(16);
152 for (i = 0; i < 16; i += 1) {
153 ipad[i] = bkey[i] ^ 0x36363636;
154 opad[i] = bkey[i] ^ 0x5C5C5C5C;
155 }
156 hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
157 return binb2rstr(binb(opad.concat(hash), 512 + 160));
158 }
159
160 /**
161 * Perform the appropriate triplet combination function for the current
162 * iteration
163 */
164 function sha1_ft(t, b, c, d) {
165 if (t < 20) {
166 return (b & c) | ((~b) & d);
167 }
168 if (t < 40) {
169 return b ^ c ^ d;
170 }
171 if (t < 60) {
172 return (b & c) | (b & d) | (c & d);
173 }
174 return b ^ c ^ d;
175 }
176
177 /**
178 * Determine the appropriate additive constant for the current iteration
179 */
180 function sha1_kt(t) {
181 return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
182 (t < 60) ? -1894007588 : -899497514;
183 }
184};
185
186export default SHA1;