UNPKG

@gandlaf21/bc-ur

Version:

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

138 lines 6.27 kB
import { bufferXOR, getCRC, split, toUint32 } from "./utils"; import { chooseFragments } from "./fountainUtils"; import { cborEncode, cborDecode } from './cbor'; import { Buffer } from "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 = cborEncode([ this._seqNum, this._seqLength, this._messageLength, this._checksum, this._fragment ]); return 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 = 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.isBuffer(fragment) && fragment.length <= 0) { throw new Error("type error"); } return new FountainEncoderPart(seqNum, seqLength, messageLength, checksum, Buffer.from(fragment)); }; return FountainEncoderPart; }()); export { 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 = toUint32(firstSeqNum); this.checksum = 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 bufferXOR(_this._fragments[index], result); }, Buffer.alloc(this.fragmentLength, 0)); }; FountainEncoder.prototype.nextPart = function () { this.seqNum = toUint32(this.seqNum + 1); var indexes = 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.from(message); var fragment; var _fragments = []; while (remaining.length > 0) { _a = split(remaining, -fragmentLength), fragment = _a[0], remaining = _a[1]; fragment = Buffer .alloc(fragmentLength, 0) // initialize with 0's to achieve the padding .fill(fragment, 0, fragment.length); _fragments.push(fragment); } return _fragments; }; return FountainEncoder; }()); export default FountainEncoder; //# sourceMappingURL=fountainEncoder.js.map