JavaScript generic ASN.1 parser (mirror)
at github-101 112 lines 3.3 kB view raw
1// Big integer base-10 printing library 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 16/** Biggest 10^n integer that can still fit 2^53 when multiplied by 256. */ 17const max = 10000000000000; 18 19export class Int10 { 20 /** 21 * Arbitrary length base-10 value. 22 * @param {number} value - Optional initial value (will be 0 otherwise). 23 */ 24 constructor(value) { 25 this.buf = [+value || 0]; 26 } 27 28 /** 29 * Multiply value by m and add c. 30 * @param {number} m - multiplier, must be 0<m<=256 31 * @param {number} c - value to add, must be c>=0 32 */ 33 mulAdd(m, c) { 34 // assert(m > 0) 35 // assert(m <= 256) 36 // assert(c >= 0) 37 let b = this.buf, 38 l = b.length, 39 i, t; 40 for (i = 0; i < l; ++i) { 41 t = b[i] * m + c; 42 if (t < max) 43 c = 0; 44 else { 45 c = 0|(t / max); 46 t -= c * max; 47 } 48 b[i] = t; 49 } 50 if (c > 0) 51 b[i] = c; 52 } 53 54 /** 55 * Subtract value. 56 * @param {number} c - value to subtract 57 */ 58 sub(c) { 59 let b = this.buf, 60 l = b.length, 61 i, t; 62 for (i = 0; i < l; ++i) { 63 t = b[i] - c; 64 if (t < 0) { 65 t += max; 66 c = 1; 67 } else 68 c = 0; 69 b[i] = t; 70 } 71 while (b[b.length - 1] === 0) 72 b.pop(); 73 } 74 75 /** 76 * Convert to decimal string representation. 77 * @param {number} [base=10] - optional value, only value accepted is 10 78 * @returns {string} The decimal string representation. 79 */ 80 toString(base = 10) { 81 if (base != 10) 82 throw new Error('only base 10 is supported'); 83 let b = this.buf, 84 s = b[b.length - 1].toString(); 85 for (let i = b.length - 2; i >= 0; --i) 86 s += (max + b[i]).toString().substring(1); 87 return s; 88 } 89 90 /** 91 * Convert to Number value representation. 92 * Will probably overflow 2^53 and thus become approximate. 93 * @returns {number} The numeric value. 94 */ 95 valueOf() { 96 let b = this.buf, 97 v = 0; 98 for (let i = b.length - 1; i >= 0; --i) 99 v = v * max + b[i]; 100 return v; 101 } 102 103 /** 104 * Return value as a simple Number (if it is <= 10000000000000), or return this. 105 * @returns {number | Int10} The simplified value. 106 */ 107 simplify() { 108 let b = this.buf; 109 return (b.length == 1) ? b[0] : this; 110 } 111 112}