首次放到 git
This commit is contained in:
224
utils/convert.js
Normal file
224
utils/convert.js
Normal file
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* Conversion Utilities
|
||||
*
|
||||
*/
|
||||
|
||||
var defineProperty = require('./properties.js').defineProperty;
|
||||
|
||||
var errors = require('./errors');
|
||||
|
||||
function addSlice(array) {
|
||||
if (array.slice) { return array; }
|
||||
|
||||
array.slice = function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
return new Uint8Array(Array.prototype.slice.apply(array, args));
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
function isArrayish(value) {
|
||||
if (!value || parseInt(value.length) != value.length || typeof(value) === 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
var v = value[i];
|
||||
if (v < 0 || v >= 256 || parseInt(v) != v) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function arrayify(value) {
|
||||
if (value == null) {
|
||||
errors.throwError('cannot convert null value to array', errors.INVALID_ARGUMENT, { arg: 'value', value: value });
|
||||
}
|
||||
|
||||
if (value && value.toHexString) {
|
||||
value = value.toHexString();
|
||||
}
|
||||
|
||||
if (isHexString(value)) {
|
||||
value = value.substring(2);
|
||||
if (value.length % 2) { value = '0' + value; }
|
||||
|
||||
var result = [];
|
||||
for (var i = 0; i < value.length; i += 2) {
|
||||
result.push(parseInt(value.substr(i, 2), 16));
|
||||
}
|
||||
|
||||
return addSlice(new Uint8Array(result));
|
||||
|
||||
} else if (typeof(value) === 'string') {
|
||||
if (value.match(/^[0-9a-fA-F]*$/)) {
|
||||
errors.throwError('hex string must have 0x prefix', errors.INVALID_ARGUMENT, { arg: 'value', value: value });
|
||||
}
|
||||
errors.throwError('invalid hexidecimal string', errors.INVALID_ARGUMENT, { arg: 'value', value: value });
|
||||
}
|
||||
|
||||
if (isArrayish(value)) {
|
||||
return addSlice(new Uint8Array(value));
|
||||
}
|
||||
|
||||
errors.throwError('invalid arrayify value', { arg: 'value', value: value, type: typeof(value) });
|
||||
}
|
||||
|
||||
function concat(objects) {
|
||||
var arrays = [];
|
||||
var length = 0;
|
||||
for (var i = 0; i < objects.length; i++) {
|
||||
var object = arrayify(objects[i])
|
||||
arrays.push(object);
|
||||
length += object.length;
|
||||
}
|
||||
|
||||
var result = new Uint8Array(length);
|
||||
var offset = 0;
|
||||
for (var i = 0; i < arrays.length; i++) {
|
||||
result.set(arrays[i], offset);
|
||||
offset += arrays[i].length;
|
||||
}
|
||||
|
||||
return addSlice(result);
|
||||
}
|
||||
function stripZeros(value) {
|
||||
value = arrayify(value);
|
||||
|
||||
if (value.length === 0) { return value; }
|
||||
|
||||
// Find the first non-zero entry
|
||||
var start = 0;
|
||||
while (value[start] === 0) { start++ }
|
||||
|
||||
// If we started with zeros, strip them
|
||||
if (start) {
|
||||
value = value.slice(start);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function padZeros(value, length) {
|
||||
value = arrayify(value);
|
||||
|
||||
if (length < value.length) { throw new Error('cannot pad'); }
|
||||
|
||||
var result = new Uint8Array(length);
|
||||
result.set(value, length - value.length);
|
||||
return addSlice(result);
|
||||
}
|
||||
|
||||
|
||||
function isHexString(value, length) {
|
||||
if (typeof(value) !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) {
|
||||
return false
|
||||
}
|
||||
if (length && value.length !== 2 + 2 * length) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
var HexCharacters = '0123456789abcdef';
|
||||
|
||||
function hexlify(value) {
|
||||
|
||||
if (value && value.toHexString) {
|
||||
return value.toHexString();
|
||||
}
|
||||
|
||||
if (typeof(value) === 'number') {
|
||||
if (value < 0) {
|
||||
errors.throwError('cannot hexlify negative value', errors.INVALID_ARG, { arg: 'value', value: value });
|
||||
}
|
||||
|
||||
var hex = '';
|
||||
while (value) {
|
||||
hex = HexCharacters[value & 0x0f] + hex;
|
||||
value = parseInt(value / 16);
|
||||
}
|
||||
|
||||
if (hex.length) {
|
||||
if (hex.length % 2) { hex = '0' + hex; }
|
||||
return '0x' + hex;
|
||||
}
|
||||
|
||||
return '0x00';
|
||||
}
|
||||
|
||||
if (isHexString(value)) {
|
||||
if (value.length % 2) {
|
||||
value = '0x0' + value.substring(2);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
if (isArrayish(value)) {
|
||||
var result = [];
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
var v = value[i];
|
||||
result.push(HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f]);
|
||||
}
|
||||
return '0x' + result.join('');
|
||||
}
|
||||
|
||||
errors.throwError('invalid hexlify value', { arg: 'value', value: value });
|
||||
}
|
||||
|
||||
function hexStripZeros(value) {
|
||||
while (value.length > 3 && value.substring(0, 3) === '0x0') {
|
||||
value = '0x' + value.substring(3);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function hexZeroPad(value, length) {
|
||||
while (value.length < 2 * length + 2) {
|
||||
value = '0x0' + value.substring(2);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/* @TODO: Add something like this to make slicing code easier to understand
|
||||
function hexSlice(hex, start, end) {
|
||||
hex = hexlify(hex);
|
||||
return '0x' + hex.substring(2 + start * 2, 2 + end * 2);
|
||||
}
|
||||
*/
|
||||
|
||||
function splitSignature(signature) {
|
||||
signature = arrayify(signature);
|
||||
if (signature.length !== 65) {
|
||||
throw new Error('invalid signature');
|
||||
}
|
||||
|
||||
var v = signature[64];
|
||||
if (v !== 27 && v !== 28) {
|
||||
v = 27 + (v % 2);
|
||||
}
|
||||
|
||||
return {
|
||||
r: hexlify(signature.slice(0, 32)),
|
||||
s: hexlify(signature.slice(32, 64)),
|
||||
v: v
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
arrayify: arrayify,
|
||||
isArrayish: isArrayish,
|
||||
|
||||
concat: concat,
|
||||
|
||||
padZeros: padZeros,
|
||||
stripZeros: stripZeros,
|
||||
|
||||
splitSignature: splitSignature,
|
||||
|
||||
hexlify: hexlify,
|
||||
isHexString: isHexString,
|
||||
hexStripZeros: hexStripZeros,
|
||||
hexZeroPad: hexZeroPad,
|
||||
};
|
||||
Reference in New Issue
Block a user