UNPKG

@gandlaf21/bc-ur

Version:

A JS implementation of the Uniform Resources (UR) specification from Blockchain Commons

141 lines (140 loc) 6.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FountainEncoderPart = void 0; var utils_1 = require("./utils"); var fountainUtils_1 = require("./fountainUtils"); var cbor_1 = require("./cbor"); var buffer_1 = require("buffer"); var FountainEncoderPart = /** @class */ (function () { function FountainEncoderPart(_seqNum, _seqLength, _messageLength, _checksum, _fragment) { this._seqNum = _seqNum; this._seqLength = _seqLength; this._messageLength = _messageLength; this._checksum = _checksum; this._fragment = _fragment; } Object.defineProperty(FountainEncoderPart.prototype, "messageLength", { get: function () { return this._messageLength; }, enumerable: false, configurable: true }); Object.defineProperty(FountainEncoderPart.prototype, "fragment", { get: function () { return this._fragment; }, enumerable: false, configurable: true }); Object.defineProperty(FountainEncoderPart.prototype, "seqNum", { get: function () { return this._seqNum; }, enumerable: false, configurable: true }); Object.defineProperty(FountainEncoderPart.prototype, "seqLength", { get: function () { return this._seqLength; }, enumerable: false, configurable: true }); Object.defineProperty(FountainEncoderPart.prototype, "checksum", { get: function () { return this._checksum; }, enumerable: false, configurable: true }); FountainEncoderPart.prototype.cbor = function () { var result = cbor_1.cborEncode([ this._seqNum, this._seqLength, this._messageLength, this._checksum, this._fragment ]); return buffer_1.Buffer.from(result); }; FountainEncoderPart.prototype.description = function () { return "seqNum:" + this._seqNum + ", seqLen:" + this._seqLength + ", messageLen:" + this._messageLength + ", checksum:" + this._checksum + ", data:" + this._fragment.toString('hex'); }; FountainEncoderPart.fromCBOR = function (cborPayload) { var _a = cbor_1.cborDecode(cborPayload), seqNum = _a[0], seqLength = _a[1], messageLength = _a[2], checksum = _a[3], fragment = _a[4]; if (typeof seqNum !== 'number' || typeof seqLength !== 'number' || typeof messageLength !== 'number' || typeof checksum !== 'number' || buffer_1.Buffer.isBuffer(fragment) && fragment.length <= 0) { throw new Error("type error"); } return new FountainEncoderPart(seqNum, seqLength, messageLength, checksum, buffer_1.Buffer.from(fragment)); }; return FountainEncoderPart; }()); exports.FountainEncoderPart = FountainEncoderPart; var FountainEncoder = /** @class */ (function () { function FountainEncoder(message, maxFragmentLength, firstSeqNum, minFragmentLength) { if (maxFragmentLength === void 0) { maxFragmentLength = 100; } if (firstSeqNum === void 0) { firstSeqNum = 0; } if (minFragmentLength === void 0) { minFragmentLength = 10; } var fragmentLength = FountainEncoder.findNominalFragmentLength(message.length, minFragmentLength, maxFragmentLength); this._messageLength = message.length; this._fragments = FountainEncoder.partitionMessage(message, fragmentLength); this.fragmentLength = fragmentLength; this.seqNum = utils_1.toUint32(firstSeqNum); this.checksum = utils_1.getCRC(message); } Object.defineProperty(FountainEncoder.prototype, "fragmentsLength", { get: function () { return this._fragments.length; }, enumerable: false, configurable: true }); Object.defineProperty(FountainEncoder.prototype, "fragments", { get: function () { return this._fragments; }, enumerable: false, configurable: true }); Object.defineProperty(FountainEncoder.prototype, "messageLength", { get: function () { return this._messageLength; }, enumerable: false, configurable: true }); FountainEncoder.prototype.isComplete = function () { return this.seqNum >= this._fragments.length; }; FountainEncoder.prototype.isSinglePart = function () { return this._fragments.length === 1; }; FountainEncoder.prototype.seqLength = function () { return this._fragments.length; }; FountainEncoder.prototype.mix = function (indexes) { var _this = this; return indexes.reduce(function (result, index) { return utils_1.bufferXOR(_this._fragments[index], result); }, buffer_1.Buffer.alloc(this.fragmentLength, 0)); }; FountainEncoder.prototype.nextPart = function () { this.seqNum = utils_1.toUint32(this.seqNum + 1); var indexes = fountainUtils_1.chooseFragments(this.seqNum, this._fragments.length, this.checksum); var mixed = this.mix(indexes); return new FountainEncoderPart(this.seqNum, this._fragments.length, this._messageLength, this.checksum, mixed); }; FountainEncoder.findNominalFragmentLength = function (messageLength, minFragmentLength, maxFragmentLength) { if (messageLength <= 0 || minFragmentLength <= 0 || maxFragmentLength < minFragmentLength) { throw new Error("invalid fragment or message length"); } var maxFragmentCount = Math.ceil(messageLength / minFragmentLength); var fragmentLength = 0; for (var fragmentCount = 1; fragmentCount <= maxFragmentCount; fragmentCount++) { fragmentLength = Math.ceil(messageLength / fragmentCount); if (fragmentLength <= maxFragmentLength) { break; } } return fragmentLength; }; FountainEncoder.partitionMessage = function (message, fragmentLength) { var _a; var remaining = buffer_1.Buffer.from(message); var fragment; var _fragments = []; while (remaining.length > 0) { _a = utils_1.split(remaining, -fragmentLength), fragment = _a[0], remaining = _a[1]; fragment = buffer_1.Buffer .alloc(fragmentLength, 0) // initialize with 0's to achieve the padding .fill(fragment, 0, fragment.length); _fragments.push(fragment); } return _fragments; }; return FountainEncoder; }()); exports.default = FountainEncoder;