JavaScript generic ASN.1 parser (mirror)
at github-101 2.6 kB view raw
1// Hex JavaScript decoder 2// Copyright (c) 2008 Lapo Luchini <lapo@lapo.it> 3 4// Permission to use, copy, modify, and/or distribute this software for any 5// purpose with or without fee is hereby granted, provided that the above 6// copyright notice and this permission notice appear in all copies. 7// 8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 16const 17 haveU8 = (typeof Uint8Array == 'function'); 18 19let decoder; // populated on first usage 20 21export class Hex { 22 23 /** 24 * Decodes an hexadecimal value. 25 * @param {string|Array|Uint8Array} a - a string representing hexadecimal data, or an array representation of its charcodes 26 */ 27 static decode(a) { 28 let isString = (typeof a == 'string'); 29 let i; 30 if (decoder === undefined) { 31 let hex = '0123456789ABCDEF', 32 ignore = ' \f\n\r\t\u00A0\u2028\u2029'; 33 decoder = []; 34 for (i = 0; i < 16; ++i) 35 decoder[hex.charCodeAt(i)] = i; 36 hex = hex.toLowerCase(); 37 for (i = 10; i < 16; ++i) 38 decoder[hex.charCodeAt(i)] = i; 39 for (i = 0; i < ignore.length; ++i) 40 decoder[ignore.charCodeAt(i)] = -1; 41 } 42 let out = haveU8 ? new Uint8Array(a.length >> 1) : [], 43 bits = 0, 44 char_count = 0, 45 len = 0; 46 for (i = 0; i < a.length; ++i) { 47 let c = isString ? a.charCodeAt(i) : a[i]; 48 c = decoder[c]; 49 if (c == -1) 50 continue; 51 if (c === undefined) 52 throw 'Illegal character at offset ' + i; 53 bits |= c; 54 if (++char_count >= 2) { 55 out[len++] = bits; 56 bits = 0; 57 char_count = 0; 58 } else { 59 bits <<= 4; 60 } 61 } 62 if (char_count) 63 throw 'Hex encoding incomplete: 4 bits missing'; 64 if (haveU8 && out.length > len) // in case it was originally longer because of ignored characters 65 out = out.subarray(0, len); 66 return out; 67 } 68 69}