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