anyid
Version:
A simple and flexible API to generate various kinds of string ID / code.
92 lines • 3.56 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const _ = __importStar(require("lodash"));
const BIT_MASKS = _.range(0, 31).map((i) => ~(0xFFFFFFFF << i));
function normalize(source, bits) {
const sourceSignificantBytes = Math.ceil(bits / 8);
assert_1.default(source.length >= sourceSignificantBytes, 'Source buffer has no enought bits');
const targetLength = Math.ceil(bits / 32) * 4;
const target = Buffer.alloc(targetLength);
source.copy(target, targetLength - sourceSignificantBytes, source.length - sourceSignificantBytes);
const unusedBits = targetLength * 8 - bits;
if (unusedBits > 0) {
let highestBytes = target.readUInt32BE(0);
highestBytes = highestBytes & BIT_MASKS[32 - unusedBits];
target.writeUInt32BE(highestBytes, 0);
}
return target;
}
exports.normalize = normalize;
function concatBits(buf1, bits1, buf2, bits2) {
const buf = Buffer.allocUnsafe(Math.ceil((bits1 + bits2) / 32) * 4);
const buf2SignificantBytes = Math.ceil(bits2 / 8);
let targetOffset = buf.length - buf2SignificantBytes;
buf2.copy(buf, targetOffset, buf2.length - buf2SignificantBytes);
targetOffset = buf.length - Math.ceil(bits2 / 32) * 4;
const filledBitsInTarget = bits2 % 32;
if (filledBitsInTarget === 0) {
targetOffset -= 4;
}
const sourceBuf = normalize(buf1, bits1);
let sourceReadOffset = sourceBuf.length;
let uncopiedBytes = sourceBuf.length;
while (uncopiedBytes > 0) {
sourceReadOffset -= 4;
const source4bytes = sourceBuf.readUInt32BE(sourceReadOffset);
let target4bytes = buf.readUInt32BE(targetOffset);
target4bytes =
(target4bytes & BIT_MASKS[filledBitsInTarget] |
source4bytes << filledBitsInTarget)
>>> 0;
buf.writeUInt32BE(target4bytes, targetOffset);
if (filledBitsInTarget > 0 && targetOffset > 0) {
target4bytes = source4bytes >>> (32 - filledBitsInTarget);
const bytesToWrite = targetOffset > 4 ? 4 : targetOffset;
buf.writeUIntBE(target4bytes, targetOffset - bytesToWrite, bytesToWrite);
}
targetOffset -= 4;
uncopiedBytes -= 4;
}
return buf;
}
exports.concatBits = concatBits;
function padBuffer(buf, bytes) {
if (buf.length >= bytes) {
return buf;
}
const target = Buffer.alloc(bytes);
buf.copy(target, bytes - buf.length);
return target;
}
function uintToBuffer(n, bytes) {
const byteArray = [];
while (n >= 256) {
byteArray.unshift(n % 256);
n = Math.floor(n / 256);
}
byteArray.unshift(n);
if (bytes && byteArray.length < bytes) {
_.times(bytes - byteArray.length, () => byteArray.unshift(0));
}
return Buffer.from(byteArray);
}
exports.uintToBuffer = uintToBuffer;
function toBuffer(v, bytes) {
if (typeof v === 'number') {
return uintToBuffer(v, bytes);
}
return bytes ? padBuffer(v, bytes) : v;
}
exports.toBuffer = toBuffer;
//# sourceMappingURL=utils.js.map