urbit-ob

JavaScript utilities for phonemic base wrangling.
Log | Files | Refs | README

commit cdb6ca8fdb227112f59d12c6163b8b8910785a00
parent b1fd6f53459701fe310c3be0d738d3ee417e6d01
Author: Jared Tobin <jared@jtobin.io>
Date:   Sat, 10 Nov 2018 19:09:30 +1300

Preserve leading zeros in patq2hex/hex2patq.

Ensures that we don't chop off leading zeros when converting between
representations.  Even though the resulting @q values are considered
equal, the behaviour can make string manipulation annoying.

Diffstat:
Msrc/internal/co.js | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mtest/co.test.js | 6+++---
2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/src/internal/co.js b/src/internal/co.js @@ -126,6 +126,15 @@ const hex2patp = (hex) => patp(new BN(hex, 'hex')) /** + * Convert a Buffer to a @p-encoded string. + * + * @param {Buffer} buf + * @return {String} + */ +const buf2patp = (buf) => + hex2patp(buf.toString('hex')) + +/** * Convert a @p-encoded string to a hex-encoded string. * * @param {String} name @p @@ -147,10 +156,22 @@ const patp2hex = (name) => { '') const bn = new BN(addr, 2) - return ob.fend(bn).toString('hex') + const hex = ob.fend(bn).toString('hex') + return hex.length % 2 !== 0 + ? hex.padStart(hex.length + 1, '0') + : hex } /** + * Convert a @p-encoded string to a Buffer. + * + * @param {String} name + * @return {Buffer} + */ +const patp2buf = name => + Buffer.from(patp2hex(name), 'hex') + +/** * Convert a @p-encoded string to a bignum. * * @param {String} name @p @@ -175,10 +196,18 @@ const patp2dec = name => * @return {String} */ const patq = (arg) => { - const n = new BN(arg) - - const buf = n.toArrayLike(Buffer) + const bn = new BN(arg) + const buf = bn.toArrayLike(Buffer) + return buf2patq(buf) +} +/** + * Convert a Buffer into a @q-encoded string. + * + * @param {Buffer} buf + * @return {String} + */ +const buf2patq = buf => { const chunked = buf.length % 2 !== 0 && buf.length > 1 ? lodash.concat([[buf[0]]], lodash.chunk(buf.slice(1), 2)) @@ -206,11 +235,20 @@ const patq = (arg) => { /** * Convert a hex-encoded string to a @q-encoded string. * + * Note that this preserves leading zero bytes. + * * @param {String} hex * @return {String} */ -const hex2patq = hex => - patq(new BN(hex, 'hex')) +const hex2patq = arg => { + const hex = + arg.length % 2 !== 0 + ? arg.padStart(arg.length + 1, '0') + : arg + + const buf = Buffer.from(hex, 'hex') + return buf2patq(buf) +} /** * Convert a @q-encoded string to a hex-encoded string. @@ -251,6 +289,17 @@ const patq2bn = name => new BN(patq2hex(name), 'hex') /** + * Convert a @q-encoded string to a Buffer. + * + * @param {String} name @q + * @return {Buffer} + */ +const patq2buf = name => { + const hex = patq2hex(name) + return Buffer.from(hex, 'hex') +} + +/** * Convert a @q-encoded string to a decimal-encoded string. * * @param {String} name @q @@ -362,12 +411,12 @@ const eqPatq = (p, q) => { module.exports = { patp, patp2hex, - patp2dec, hex2patp, + patp2dec, patq, patq2hex, - patq2dec, hex2patq, + patq2dec, clan, sein, eqPatq diff --git a/test/co.test.js b/test/co.test.js @@ -1,15 +1,15 @@ const BN = require('bn.js') -const { expect } = require('chai'); +const { expect } = require('chai') const jsc = require('jsverify') const { patp, patp2hex, - patp2dec, hex2patp, + patp2dec, patq, patq2hex, - patq2dec, hex2patq, + patq2dec, clan, sein, eqPatq