OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** @fileoverview Various string utility functions */ | 5 /** @fileoverview Various string utility functions */ |
6 'use strict'; | 6 'use strict'; |
7 | 7 |
8 /** | 8 /** |
9 * Converts a string to an array of bytes. | 9 * Converts a string to an array of bytes. |
10 * @param {string} s The string to convert. | 10 * @param {string} s The string to convert. |
(...skipping 16 matching lines...) Expand all Loading... |
27 function UTIL_BytesToString(b) { | 27 function UTIL_BytesToString(b) { |
28 return String.fromCharCode.apply(null, b); | 28 return String.fromCharCode.apply(null, b); |
29 } | 29 } |
30 | 30 |
31 /** | 31 /** |
32 * Converts a byte array to a hex string. | 32 * Converts a byte array to a hex string. |
33 * @param {(Uint8Array|Array<number>)} b input byte array. | 33 * @param {(Uint8Array|Array<number>)} b input byte array. |
34 * @return {string} result. | 34 * @return {string} result. |
35 */ | 35 */ |
36 function UTIL_BytesToHex(b) { | 36 function UTIL_BytesToHex(b) { |
37 if (!b) return '(null)'; | 37 if (!b) |
| 38 return '(null)'; |
38 var hexchars = '0123456789ABCDEF'; | 39 var hexchars = '0123456789ABCDEF'; |
39 var hexrep = new Array(b.length * 2); | 40 var hexrep = new Array(b.length * 2); |
40 | 41 |
41 for (var i = 0; i < b.length; ++i) { | 42 for (var i = 0; i < b.length; ++i) { |
42 hexrep[i * 2 + 0] = hexchars.charAt((b[i] >> 4) & 15); | 43 hexrep[i * 2 + 0] = hexchars.charAt((b[i] >> 4) & 15); |
43 hexrep[i * 2 + 1] = hexchars.charAt(b[i] & 15); | 44 hexrep[i * 2 + 1] = hexchars.charAt(b[i] & 15); |
44 } | 45 } |
45 return hexrep.join(''); | 46 return hexrep.join(''); |
46 } | 47 } |
47 | 48 |
48 function UTIL_BytesToHexWithSeparator(b, sep) { | 49 function UTIL_BytesToHexWithSeparator(b, sep) { |
49 var hexchars = '0123456789ABCDEF'; | 50 var hexchars = '0123456789ABCDEF'; |
50 var stride = 2 + (sep ? 1 : 0); | 51 var stride = 2 + (sep ? 1 : 0); |
51 var hexrep = new Array(b.length * stride); | 52 var hexrep = new Array(b.length * stride); |
52 | 53 |
53 for (var i = 0; i < b.length; ++i) { | 54 for (var i = 0; i < b.length; ++i) { |
54 if (sep) hexrep[i * stride + 0] = sep; | 55 if (sep) |
| 56 hexrep[i * stride + 0] = sep; |
55 hexrep[i * stride + stride - 2] = hexchars.charAt((b[i] >> 4) & 15); | 57 hexrep[i * stride + stride - 2] = hexchars.charAt((b[i] >> 4) & 15); |
56 hexrep[i * stride + stride - 1] = hexchars.charAt(b[i] & 15); | 58 hexrep[i * stride + stride - 1] = hexchars.charAt(b[i] & 15); |
57 } | 59 } |
58 return (sep ? hexrep.slice(1) : hexrep).join(''); | 60 return (sep ? hexrep.slice(1) : hexrep).join(''); |
59 } | 61 } |
60 | 62 |
61 function UTIL_HexToBytes(h) { | 63 function UTIL_HexToBytes(h) { |
62 var hexchars = '0123456789ABCDEFabcdef'; | 64 var hexchars = '0123456789ABCDEFabcdef'; |
63 var res = new Uint8Array(h.length / 2); | 65 var res = new Uint8Array(h.length / 2); |
64 for (var i = 0; i < h.length; i += 2) { | 66 for (var i = 0; i < h.length; i += 2) { |
65 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) break; | 67 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) |
| 68 break; |
66 res[i / 2] = parseInt(h.substring(i, i + 2), 16); | 69 res[i / 2] = parseInt(h.substring(i, i + 2), 16); |
67 } | 70 } |
68 return res; | 71 return res; |
69 } | 72 } |
70 | 73 |
71 function UTIL_HexToArray(h) { | 74 function UTIL_HexToArray(h) { |
72 var hexchars = '0123456789ABCDEFabcdef'; | 75 var hexchars = '0123456789ABCDEFabcdef'; |
73 var res = new Array(h.length / 2); | 76 var res = new Array(h.length / 2); |
74 for (var i = 0; i < h.length; i += 2) { | 77 for (var i = 0; i < h.length; i += 2) { |
75 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) break; | 78 if (hexchars.indexOf(h.substring(i, i + 1)) == -1) |
| 79 break; |
76 res[i / 2] = parseInt(h.substring(i, i + 2), 16); | 80 res[i / 2] = parseInt(h.substring(i, i + 2), 16); |
77 } | 81 } |
78 return res; | 82 return res; |
79 } | 83 } |
80 | 84 |
81 function UTIL_equalArrays(a, b) { | 85 function UTIL_equalArrays(a, b) { |
82 if (!a || !b) return false; | 86 if (!a || !b) |
83 if (a.length != b.length) return false; | 87 return false; |
| 88 if (a.length != b.length) |
| 89 return false; |
84 var accu = 0; | 90 var accu = 0; |
85 for (var i = 0; i < a.length; ++i) | 91 for (var i = 0; i < a.length; ++i) |
86 accu |= a[i] ^ b[i]; | 92 accu |= a[i] ^ b[i]; |
87 return accu === 0; | 93 return accu === 0; |
88 } | 94 } |
89 | 95 |
90 function UTIL_ltArrays(a, b) { | 96 function UTIL_ltArrays(a, b) { |
91 if (a.length < b.length) return true; | 97 if (a.length < b.length) |
92 if (a.length > b.length) return false; | 98 return true; |
| 99 if (a.length > b.length) |
| 100 return false; |
93 for (var i = 0; i < a.length; ++i) { | 101 for (var i = 0; i < a.length; ++i) { |
94 if (a[i] < b[i]) return true; | 102 if (a[i] < b[i]) |
95 if (a[i] > b[i]) return false; | 103 return true; |
| 104 if (a[i] > b[i]) |
| 105 return false; |
96 } | 106 } |
97 return false; | 107 return false; |
98 } | 108 } |
99 | 109 |
100 function UTIL_gtArrays(a, b) { | 110 function UTIL_gtArrays(a, b) { |
101 return UTIL_ltArrays(b, a); | 111 return UTIL_ltArrays(b, a); |
102 } | 112 } |
103 | 113 |
104 function UTIL_geArrays(a, b) { | 114 function UTIL_geArrays(a, b) { |
105 return !UTIL_ltArrays(a, b); | 115 return !UTIL_ltArrays(a, b); |
(...skipping 11 matching lines...) Expand all Loading... |
117 for (var k in obj) { | 127 for (var k in obj) { |
118 union.push(obj[k]); | 128 union.push(obj[k]); |
119 } | 129 } |
120 return union; | 130 return union; |
121 } | 131 } |
122 | 132 |
123 function UTIL_getRandom(a) { | 133 function UTIL_getRandom(a) { |
124 var tmp = new Array(a); | 134 var tmp = new Array(a); |
125 var rnd = new Uint8Array(a); | 135 var rnd = new Uint8Array(a); |
126 window.crypto.getRandomValues(rnd); // Yay! | 136 window.crypto.getRandomValues(rnd); // Yay! |
127 for (var i = 0; i < a; ++i) tmp[i] = rnd[i] & 255; | 137 for (var i = 0; i < a; ++i) |
| 138 tmp[i] = rnd[i] & 255; |
128 return tmp; | 139 return tmp; |
129 } | 140 } |
130 | 141 |
131 function UTIL_setFavicon(icon) { | 142 function UTIL_setFavicon(icon) { |
132 // Construct a new favion link tag | 143 // Construct a new favion link tag |
133 var faviconLink = document.createElement('link'); | 144 var faviconLink = document.createElement('link'); |
134 faviconLink.rel = 'Shortcut Icon'; | 145 faviconLink.rel = 'Shortcut Icon'; |
135 faviconLink.type = 'image/x-icon'; | 146 faviconLink.type = 'image/x-icon'; |
136 faviconLink.href = icon; | 147 faviconLink.href = icon; |
137 | 148 |
(...skipping 24 matching lines...) Expand all Loading... |
162 var UTIL_ASN_INT = 0x02; | 173 var UTIL_ASN_INT = 0x02; |
163 /** @const */ | 174 /** @const */ |
164 var UTIL_ASN_SEQUENCE = 0x30; | 175 var UTIL_ASN_SEQUENCE = 0x30; |
165 | 176 |
166 /** | 177 /** |
167 * Parse SEQ(INT, INT) from ASN1 byte array. | 178 * Parse SEQ(INT, INT) from ASN1 byte array. |
168 * @param {(Uint8Array|Array<number>)} a input to parse from. | 179 * @param {(Uint8Array|Array<number>)} a input to parse from. |
169 * @return {{'r': !Array<number>, 's': !Array<number>}|null} | 180 * @return {{'r': !Array<number>, 's': !Array<number>}|null} |
170 */ | 181 */ |
171 function UTIL_Asn1SignatureToJson(a) { | 182 function UTIL_Asn1SignatureToJson(a) { |
172 if (a.length < 6) return null; // Too small to be valid | 183 if (a.length < 6) |
173 if (a[0] != UTIL_ASN_SEQUENCE) return null; | 184 return null; // Too small to be valid |
| 185 if (a[0] != UTIL_ASN_SEQUENCE) |
| 186 return null; |
174 var l = a[1] & 255; | 187 var l = a[1] & 255; |
175 if (l & 0x80) return null; // SEQ.size too large | 188 if (l & 0x80) |
176 if (a.length != 2 + l) return null; // SEQ size does not match input | 189 return null; // SEQ.size too large |
| 190 if (a.length != 2 + l) |
| 191 return null; // SEQ size does not match input |
177 | 192 |
178 function parseInt(off) { | 193 function parseInt(off) { |
179 if (a[off] != UTIL_ASN_INT) return null; | 194 if (a[off] != UTIL_ASN_INT) |
| 195 return null; |
180 var l = a[off + 1] & 255; | 196 var l = a[off + 1] & 255; |
181 if (l & 0x80) return null; // INT.size too large | 197 if (l & 0x80) |
182 if (off + 2 + l > a.length) return null; // Out of bounds | 198 return null; // INT.size too large |
| 199 if (off + 2 + l > a.length) |
| 200 return null; // Out of bounds |
183 return a.slice(off + 2, off + 2 + l); | 201 return a.slice(off + 2, off + 2 + l); |
184 } | 202 } |
185 | 203 |
186 var r = parseInt(2); | 204 var r = parseInt(2); |
187 if (!r) return null; | 205 if (!r) |
| 206 return null; |
188 | 207 |
189 var s = parseInt(2 + 2 + r.length); | 208 var s = parseInt(2 + 2 + r.length); |
190 if (!s) return null; | 209 if (!s) |
| 210 return null; |
191 | 211 |
192 return {'r': r, 's': s}; | 212 return {'r': r, 's': s}; |
193 } | 213 } |
194 | 214 |
195 /** | 215 /** |
196 * Encode a JSON signature {r,s} as an ASN1 SEQ(INT, INT). May modify sig | 216 * Encode a JSON signature {r,s} as an ASN1 SEQ(INT, INT). May modify sig |
197 * @param {{'r': (!Array<number>|undefined), 's': !Array<number>}} sig | 217 * @param {{'r': (!Array<number>|undefined), 's': !Array<number>}} sig |
198 * @return {!Uint8Array} | 218 * @return {!Uint8Array} |
199 */ | 219 */ |
200 function UTIL_JsonSignatureToAsn1(sig) { | 220 function UTIL_JsonSignatureToAsn1(sig) { |
(...skipping 20 matching lines...) Expand all Loading... |
221 i += rbytes.length; | 241 i += rbytes.length; |
222 | 242 |
223 buf[i++] = UTIL_ASN_INT; | 243 buf[i++] = UTIL_ASN_INT; |
224 buf[i++] = sbytes.length; | 244 buf[i++] = sbytes.length; |
225 buf.set(sbytes, i); | 245 buf.set(sbytes, i); |
226 | 246 |
227 return buf; | 247 return buf; |
228 } | 248 } |
229 | 249 |
230 function UTIL_prepend_zero(s, n) { | 250 function UTIL_prepend_zero(s, n) { |
231 if (s.length == n) return s; | 251 if (s.length == n) |
| 252 return s; |
232 var l = s.length; | 253 var l = s.length; |
233 for (var i = 0; i < n - l; ++i) { | 254 for (var i = 0; i < n - l; ++i) { |
234 s = '0' + s; | 255 s = '0' + s; |
235 } | 256 } |
236 return s; | 257 return s; |
237 } | 258 } |
238 | 259 |
239 // hr:min:sec.milli string | 260 // hr:min:sec.milli string |
240 function UTIL_time() { | 261 function UTIL_time() { |
241 var d = new Date(); | 262 var d = new Date(); |
(...skipping 10 matching lines...) Expand all Loading... |
252 var UTIL_max_events = 500; | 273 var UTIL_max_events = 500; |
253 | 274 |
254 function UTIL_fmt(s) { | 275 function UTIL_fmt(s) { |
255 var line = UTIL_time() + ': ' + s; | 276 var line = UTIL_time() + ': ' + s; |
256 if (UTIL_events.push(line) > UTIL_max_events) { | 277 if (UTIL_events.push(line) > UTIL_max_events) { |
257 // Drop from head. | 278 // Drop from head. |
258 UTIL_events.splice(0, UTIL_events.length - UTIL_max_events); | 279 UTIL_events.splice(0, UTIL_events.length - UTIL_max_events); |
259 } | 280 } |
260 return line; | 281 return line; |
261 } | 282 } |
OLD | NEW |