You are missing the padding in the hex conversion. You'll want to use
function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
so that each byte transforms to exactly two hex digits. Your expected output would be 04812d7e3a9829e5d51bdd64ceb35df060699bc1309731bd6e6f1a5443a7f9ce0af4382fcfd6f5f8a08bb2619709c2d49fb771601770f2c267985af2754e1f8cf9
You are missing the padding in the hex conversion. You'll want to use
function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
so that each byte transforms to exactly two hex digits. Your expected output would be 04812d7e3a9829e5d51bdd64ceb35df060699bc1309731bd6e6f1a5443a7f9ce0af4382fcfd6f5f8a08bb2619709c2d49fb771601770f2c267985af2754e1f8cf9
Using map() won't work if the input is of a type like Uint8Array: the result of map() is also Uint8Array which can't hold the results of string conversion.
function toHexString(byteArray) {
var s = '0x';
byteArray.forEach(function(byte) {
s += ('0' + (byte & 0xFF).toString(16)).slice(-2);
});
return s;
}
javascript - How to convert hex string into a bytes array, and a bytes array in the hex string? - Stack Overflow
cryptography - Byte array to hexadecimal and back again in JavaScript - Bitcoin Stack Exchange
javascript - How to convert byte array to hex string? - Stack Overflow
javascript - Converting a hex string into a BYTE array JS - Stack Overflow
Convert a hex string to a byte array and vice versa
note: implementation from crypto-js, though now out of date and slightly altered
// Convert a hex string to a byte array
function hexToBytes(hex) {
let bytes = [];
for (let c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes;
}
// Convert a byte array to a hex string
function bytesToHex(bytes) {
let hex = [];
for (let i = 0; i < bytes.length; i++) {
let current = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];
hex.push((current >>> 4).toString(16));
hex.push((current & 0xF).toString(16));
}
return hex.join("");
}
Update: Scroll down for solution... Live Demo
The issue: you are using a lossy conversion to hex, which cannot be reversed.
var p = parseHexString(createHexString(rsa_privk[0]));
This will never be same as rsa_privk[0].
Because, createHexString() only uses the last 2 bytes from each array element.
Example:
rsa_privk[0] : [123676133, 198914513, 129998601, 245147334, 11918451, 206998232, 96766191, 75984899, 177840095, 106709334, 10180427, 208237547, 119814814, 127003446, 189062377, 84099480, 220452154, 250519075, 267883908, 115471915, 165124106, 238628722, 169382478, 42320122, 95982405, 80725759, 89608310, 85166267, 200925925, 254033325, 86971506, 191278317, 127411298, 180195794, 142776693, 188738169, 39016]
createHexString(rsa_privk[0]) : e5d109c673d8ef03df564beb9e36e9983a23842b0a724efa45ff76bbe5ad72ed62d2757968
parseHexString(createHexString(rsa_privk[0])) : [229, 209, 9, 198, 115, 216, 239, 3, 223, 86, 75, 235, 158, 54, 233, 152, 58, 35, 132, 43, 10, 114, 78, 250, 69, 255, 118, 187, 229, 173, 114, 237, 98, 210, 117, 121, 104]
Update : Working Solution...
The two functions... the hex always contains 8 byte blocks, each for each element in the array...
function parseHexString(str) {
var result = [];
while (str.length >= 8) {
result.push(parseInt(str.substring(0, 8), 16));
str = str.substring(8, str.length);
}
return result;
}
function createHexString(arr) {
var result = "";
var z;
for (var i = 0; i < arr.length; i++) {
var str = arr[i].toString(16);
z = 8 - str.length + 1;
str = Array(z).join("0") + str;
result += str;
}
return result;
}
Test code...
function test() {
a = [123676133, 198914513, 129998601, 245147334, 11918451, 206998232, 96766191, 75984899, 177840095, 106709334, 10180427, 208237547, 119814814, 127003446, 189062377, 84099480, 220452154, 250519075, 267883908, 115471915, 165124106, 238628722, 169382478, 42320122, 95982405, 80725759, 89608310, 85166267, 200925925, 254033325, 86971506, 191278317, 127411298, 180195794, 142776693, 188738169, 39016];
console.log("Input");
console.log(a);
b = createHexString(a);
console.log("Hex");
console.log(b);
c = parseHexString(b);
console.log("Output");
console.log(c);
if(checkIfEqual(a, c)) {
alert("Same");
}
}
function checkIfEqual(arr1, arr2) {
if (arr1.length != arr2.length) {
return false;
}
//sort them first, then join them and just compare the strings
return arr1.sort().join() == arr2.sort().join();
}
Your Python code is correct (although it can be written much more concise as the other answers suggest), but your JS code isn't because it clearly outputs a hex string that is not the same as the input.
Instead, fix your JS code:
function toHexString(bytes) {
return bytes.toString('hex').toUpperCase();
}
input -> Buffer.from("333138383223633D77DB", 'hex')
output -> 333138383223633D77DB
EDIT: if you really insist on Python code that outputs the same broken hex string, this may work:
import re
input = '333138383223633D77DB';
output = ''
for m in re.finditer(r'..', input):
match = m.group(0)
output += match if re.match('[0-9][0-9]', match) else '0'
print(output)
(my Python skills are extremely rusty so it may not work for all inputs, and/or it can be written much more concise)
with python 3.5+ you can use hex()
def toHexString(byteArray):
return byteArray.hex()
honestly do not think there is any need for defining any helper function when you can just run byteArray.hex()
A single liner :
'[86400:?]'.split ('').map (function (c) { return c.charCodeAt (0); })
returns
[91, 56, 54, 52, 48, 48, 58, 63, 93]
This is, of course, is an array of numbers, not strictly a "byte array". Did you really mean a "byte array"?
Split the string into individual characters then map each character to its numeric code.
Per your added information about device.write I found this :
Writing to a device
Writing to a device is performed using the write call in a device handle. All writing is synchronous.
device.write([0x00, 0x01, 0x01, 0x05, 0xff, 0xff]);
on https://npmjs.org/package/node-hid
Assuming this is what you are using then my array above would work perfectly well :
device.write('[86400:?]'.split ('').map (function (c) { return c.charCodeAt (0); }));
As has been noted the 0x notation is just that, a notation. Whether you specify 0x0a or 10 or 012 (in octal) the value is the same.
function getBytes(str){
let intArray=str.split ('').map (function (c) { return c.charCodeAt (0); });
let byteArray=new Uint8Array(intArray.length);
for (let i=0;i<intArray.length;i++)
byteArray[i]=intArray[i];
return byteArray;
}
device.write(getBytes('[86400:?]'));