blob: 16606eaef7feb1c9c789874f5e24f9b981d814de [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const assert = require('assert');
function padding(str, padding) {
const offset = padding - str.length;
return '0'.repeat(offset) + str;
}
function convertBinaryNum1(binNum, byteLength) {
let str = '';
for (let i = 0; i < byteLength; i++) {
str += padding(binNum[i].toString(2), 8);
}
return parseInt(str, 2);
}
// 在源文件中进行了搜索,发现 convertBinaryNum2 的作用就是对 big-endian 的 byte[4] 和 byte[8]
// 进行反序列化成 uint32 和 uint64,所以该实现只针对这样两种类型
function convertBinaryNum2(binNum, byteLength) {
// 感觉 byteLength 是不是可以省略,直接取 binNum.length 可以减少一些脑力负担
if (byteLength === 4) {
return binNum.readUInt32BE(0);
}
const high = binNum.readUInt32BE(0) * Math.pow(2, 32);
const low = binNum.readUInt32BE(4);
return high + low;
}
// test
assert.ok(
convertBinaryNum1(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4) === 1025,
'1 - 1025',
);
assert.ok(
convertBinaryNum1(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
) === 201212,
'1 - 201212',
);
assert.ok(
convertBinaryNum1(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
) === 13234234234234234234,
'1 - 13234234234234234234',
);
assert.ok(
convertBinaryNum2(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4) === 1025,
'2 - 1025',
);
assert.ok(
convertBinaryNum2(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
) === 201212,
'2 - 201212',
);
assert.ok(
convertBinaryNum2(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
) === 13234234234234234234,
'2 - 13234234234234234234',
);
// benchmark
console.time('1 - 1025');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum1(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4);
}
console.timeEnd('1 - 1025');
console.time('2 - 1025');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum2(Buffer.from([0x00, 0x00, 0x04, 0x01]), 4);
}
console.timeEnd('2 - 1025');
console.time('1 - 201212');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum1(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
);
}
console.timeEnd('1 - 201212');
console.time('2 - 201212');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum2(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
8,
);
}
console.timeEnd('2 - 201212');
console.time('1 - 13234234234234234234');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum1(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
);
}
console.timeEnd('1 - 13234234234234234234');
console.time('2 - 13234234234234234234');
for (let i = 0; i < 1000000; i++) {
convertBinaryNum2(
Buffer.from([0xb7, 0xa9, 0x71, 0xeb, 0x05, 0xd8, 0x68, 0x00]),
8,
);
}
console.timeEnd('2 - 13234234234234234234');
function toBytes4(num) {
assert.ok(num >= 0 && num <= 0xffffffff);
const buf = Buffer.allocUnsafe(4);
buf.writeUInt32BE(num, 0);
return buf;
}
function toBytes8(num) {
assert.ok(num >= 0 && num <= Number.MAX_SAFE_INTEGER);
const buf = Buffer.allocUnsafe(8);
const high = Math.floor(num / Math.pow(2, 32));
const low = (num & 0xffffffff) >>> 0;
buf.writeUInt32BE(high);
buf.writeUInt32BE(low, 4);
return buf;
}
function fromBytes4(buf) {
return buf.readUInt32BE(0);
}
function fromBytes8(buf) {
const high = buf.readUInt32BE(0);
assert(high <= 0x1fffff);
const low = buf.readUInt32BE(4);
return high * Math.pow(2, 32) + low;
}
assert.ok(
toBytes8(201212).equals(
Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc]),
),
'toBytes8(201212)',
);
assert.ok(
toBytes8(9007199254740991).equals(
Buffer.from([0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
),
'toBytes8(9007199254740991)',
);
assert.ok(
fromBytes8(Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x11, 0xfc])) ===
201212,
'fromBytes8(201212)',
);
assert.ok(
fromBytes8(Buffer.from([0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])) ===
9007199254740991,
'fromBytes8(9007199254740991)',
);