1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | (function () {
|
14 | "use strict";
|
15 |
|
16 | var FORMATS = {
|
17 | 'dec': toDecimalString,
|
18 | 'hex': toHexString,
|
19 | 'bin': toBinaryString,
|
20 | 'oct': toOctetString
|
21 | };
|
22 |
|
23 | module.exports = function (buffer, base, options) {
|
24 | base = base || 'dec';
|
25 | var buf = _toBuffer(buffer), format = FORMATS[base];
|
26 |
|
27 | if (format) {
|
28 | return format(buf, options);
|
29 | }
|
30 | };
|
31 |
|
32 | function createBuffer(size) {
|
33 | var buf;
|
34 | if (Buffer.alloc) {
|
35 | buf = Buffer.alloc(size);
|
36 | } else {
|
37 | buf = new Buffer(size);
|
38 | buf.fill(0);
|
39 | }
|
40 | return buf;
|
41 | }
|
42 |
|
43 | function createBufferFrom(object) {
|
44 | var buf;
|
45 | if (Buffer.from) {
|
46 | buf = Buffer.from(object);
|
47 | } else {
|
48 | buf = new Buffer(object);
|
49 | }
|
50 | return buf;
|
51 | }
|
52 |
|
53 | function toDecimalString(buffer, options) {
|
54 | options = options || {};
|
55 | var bits = buffer.length * 8,
|
56 | lastBit = buffer.length - 1,
|
57 | digits = createBuffer(Math.floor(bits / 3 + 1 + 1)),
|
58 | lastDigit = digits.length - 1, carry;
|
59 |
|
60 |
|
61 | digits.fill(0);
|
62 |
|
63 |
|
64 | if ((options.format || 'BE') !== 'LE') {
|
65 | _reverseBuffer(buffer);
|
66 | }
|
67 |
|
68 | for (var i = 0; i < bits; i++) {
|
69 | carry = buffer[lastBit] >= 0x80;
|
70 |
|
71 | _leftShift(buffer);
|
72 |
|
73 | for (var d = lastDigit; d >= 0; d--) {
|
74 | digits[d] += digits[d] + (carry ? 1 : 0);
|
75 | carry = (digits[d] > 9);
|
76 | if (carry) {
|
77 | digits[d] -= 10;
|
78 | }
|
79 | }
|
80 | }
|
81 |
|
82 |
|
83 | var idx = _lastHeadIndex(digits, 0);
|
84 |
|
85 |
|
86 | idx = idx >= 0 ? idx : lastDigit;
|
87 |
|
88 |
|
89 | _toAsciiDigits(digits, idx);
|
90 |
|
91 | return _pad(
|
92 | _split(digits.toString('ascii', idx), options.groupsize, options.delimiter),
|
93 | '', options.padstr, options.size);
|
94 | }
|
95 |
|
96 | function toBinaryString(buffer, options) {
|
97 | options = options || {};
|
98 | var digits = new Array(buffer.length),
|
99 | size = options.groupsize || -1, num,
|
100 | prefix = options.prefix || '',
|
101 | output;
|
102 |
|
103 | if ((options.format || 'BE') !== 'BE') {
|
104 | _reverseBuffer(buffer);
|
105 | }
|
106 |
|
107 | for (var i = 0; i < buffer.length; i++) {
|
108 | num = buffer[i].toString(2);
|
109 | digits[i] = '00000000'.slice(0, 8 - num.length) + buffer[i].toString(2);
|
110 | }
|
111 |
|
112 | output = digits.join('');
|
113 |
|
114 | if (options.trim) {
|
115 | output = output.substr(output.indexOf('1'));
|
116 | }
|
117 |
|
118 | if (size > 0) {
|
119 | output = _split(output, size, options.delimiter);
|
120 | }
|
121 |
|
122 | return prefix + _pad(output, prefix, options.padstr, options.size);
|
123 | }
|
124 |
|
125 | |
126 |
|
127 |
|
128 |
|
129 | function toHexString(buffer, options) {
|
130 | options = options || {};
|
131 | var prefix = options.prefix || '', digits, idx;
|
132 |
|
133 | if ((options.format || 'BE') !== 'BE') {
|
134 | _reverseBuffer(buffer);
|
135 | }
|
136 |
|
137 | digits = buffer.toString('hex');
|
138 | idx = _lastHeadIndex(digits, '0');
|
139 |
|
140 |
|
141 | idx = idx >= 0 ? idx : digits.length - 1;
|
142 |
|
143 | return prefix + _pad(
|
144 | _split(digits.slice(idx), options.groupsize, options.delimiter), prefix, options.padstr, options.size);
|
145 | }
|
146 |
|
147 | function toOctetString(buffer, options) {
|
148 | options = options || {};
|
149 | var shifts = Math.floor(buffer.length * 8 / 3),
|
150 | lastIdx = buffer.length - 1,
|
151 | digits = createBuffer(shifts),
|
152 | prefix = options.prefix || '', idx;
|
153 |
|
154 | digits.fill(0);
|
155 | if ((options.format || 'BE') !== 'BE') {
|
156 | _reverseBuffer(buffer);
|
157 | }
|
158 |
|
159 | for (var i = digits.length - 1; i >= 0; i--) {
|
160 | digits[i] = buffer[lastIdx] & 0x7;
|
161 |
|
162 |
|
163 | _rightShift(buffer);
|
164 | _rightShift(buffer);
|
165 | _rightShift(buffer);
|
166 | }
|
167 |
|
168 |
|
169 | idx = _lastHeadIndex(digits, 0);
|
170 | idx = idx >= 0 ? idx : lastIdx;
|
171 |
|
172 |
|
173 | _toAsciiDigits(digits, idx);
|
174 |
|
175 | return prefix + _pad(
|
176 | _split(digits.toString('ascii', idx), options.groupsize, options.delimiter), prefix, options.padstr, options.size);
|
177 | }
|
178 |
|
179 | function _split(string, size, delim) {
|
180 | if (typeof delim === 'undefined') {
|
181 | delim = ' ';
|
182 | }
|
183 | if (typeof string !== 'undefined' && +size > 0) {
|
184 | string = string.replace(new RegExp('(.)(?=(.{' + +size + '})+(?!.))', 'g'), "$1" + delim);
|
185 | }
|
186 | return string;
|
187 | }
|
188 |
|
189 | function _pad(str, prefix, pad, size) {
|
190 | if ('undefined' === typeof pad || 'undefined' === typeof size || pad.length === 0 || str.length + prefix.length >= size) {
|
191 | return str;
|
192 | }
|
193 | var padlen = size - str.length - prefix.length;
|
194 | return new Array(Math.ceil(padlen / pad.length) + 1).join(pad).substr(0, padlen) + str;
|
195 | }
|
196 |
|
197 | function _toAsciiDigits(buffer, offset) {
|
198 | for (var i = offset; i < buffer.length; i++) {
|
199 | buffer[i] += 48;
|
200 | }
|
201 | }
|
202 |
|
203 | |
204 |
|
205 |
|
206 |
|
207 | function _lastHeadIndex(buffer, value) {
|
208 | for (var i = 0; i < buffer.length; i++) {
|
209 | if (buffer[i] !== value) {
|
210 | return i;
|
211 | }
|
212 | }
|
213 | return -1;
|
214 | }
|
215 |
|
216 | |
217 |
|
218 |
|
219 | function _toBuffer(buffer) {
|
220 | var _buffer, nums;
|
221 |
|
222 | if (Buffer.isBuffer(buffer) || Array.isArray(buffer)) {
|
223 | _buffer = createBufferFrom(buffer);
|
224 | }
|
225 | else if (typeof buffer === 'string') {
|
226 | nums = buffer.replace(/^0x/i, '').match(/.{1,2}(?=(..)+(?!.))|..?$/g);
|
227 | _buffer = createBuffer(nums.length);
|
228 |
|
229 | for (var i = nums.length - 1; i >= 0; i--) {
|
230 | _buffer.writeUInt8(parseInt(nums[i], 16), i);
|
231 | }
|
232 | }
|
233 |
|
234 | return _buffer;
|
235 | }
|
236 |
|
237 | |
238 |
|
239 |
|
240 | function _reverseBuffer(buffer) {
|
241 | var tmp, len = buffer.length - 1, half = Math.floor(buffer.length / 2);
|
242 | for (var i = len; i >= half; i--) {
|
243 | tmp = buffer[i];
|
244 | buffer[i] = buffer[len - i];
|
245 | buffer[len - i] = tmp;
|
246 | }
|
247 | }
|
248 |
|
249 | |
250 |
|
251 |
|
252 | function _leftShift(buffer) {
|
253 | var carry;
|
254 | for (var i = buffer.length; i >= 0; i--) {
|
255 | carry = (buffer[i] & 0x80) !== 0;
|
256 | buffer[i] = (buffer[i] << 1) & 0xFF;
|
257 | if (carry && i >= 0) {
|
258 | buffer[i + 1] |= 0x01;
|
259 | }
|
260 | }
|
261 | }
|
262 |
|
263 | |
264 |
|
265 |
|
266 | function _rightShift(buffer) {
|
267 | var carry, prevcarry;
|
268 | for (var i = 0; i < buffer.length; i++) {
|
269 | carry = prevcarry;
|
270 | prevcarry = (buffer[i] & 0x1) !== 0;
|
271 | buffer[i] >>= 1;
|
272 | if (carry && i > 0) {
|
273 | buffer[i] |= 0x80;
|
274 | }
|
275 | }
|
276 | }
|
277 |
|
278 | }()); |
\ | No newline at end of file |