如何将十六进制字符串转换成字节数组,以及十六进制字符串中的字节数组?

时间:2021-10-16 15:45:01

The following code procedure bytes = parseHexString (createHexString (bytes)) leads to updated of bytes, what I would like to avoid. And as a result calculations are not correct.

下面的代码过程字节= parseHexString (createHexString(字节))导致更新的字节,我想要避免的。因此,计算结果是不正确的。

<html>
<head>
<SCRIPT SRC="http://eu.static.mega.co.nz/sjcl_1.js"></SCRIPT>
<SCRIPT SRC="http://eu.static.mega.co.nz/crypto_1.js"></SCRIPT>
<SCRIPT SRC="http://eu.static.mega.co.nz/rsa_1.js"></SCRIPT>
<SCRIPT SRC="http://eu.static.mega.co.nz/hex_1.js"></SCRIPT>
<SCRIPT>
function parseHexString(str) { 
    var result = [];
    while (str.length >= 2) { 
        result.push(parseInt(str.substring(0, 2), 16));
        str = str.substring(2, str.length);
    }

    return result;
}

function createHexString(arr) {
    var result = "";
    for (i in arr) {
        var str = arr[i].toString(16);
        str = str.length == 0 ? "00" :
              str.length == 1 ? "0" + str : 
              str.length == 2 ? str :
              str.substring(str.length-2, str.length);
        result += str;
    }
    return result;
}

function t()
{
    var json_k     = 'aOrP5yLtNQT53WMQfufSlA';
    var json_csid  = 'CABD6JUMldvI_eqP0537xl9P8x7kgk2OjOq99Fy7kosphj6AFUtlbwRRDpg4EIifXRLO6FNpdD22WwtUlJ_1Mgye2Y87trEqLCbhahuEFJVQNMDtNbIem7xY2ER9uF-cdgBXZWuzp7XIBybSh7W8MSUlv_eGS6LcLGJ81Q49dSzVhcswHTJ_IJl04p3c0axR6ZIJ8dH5bJ_vXvgQsypUVVtdfMacKhB9cXdEtRZ6iWLKCKqscXdo6CNXlbIdzRhro0gxfmhfB_miysFAiSQrbtuYnIgYBU3i9p3jRlPD4ti3CUcnj0SomV61w1aEYNvo56HPMUZlVkVHA7BFzvHGHo0J';
    var json_privk = 'K7LDtk2M2QhjJx_v_Hqf0LKUBaZx76U_vBDjQty9HpFDy2MntF5HxxuyHQ9-1HmXeYzbL1pZnAxsZ7LRUbDnkR6qtJVaGdWuQhrytkuq0l5zBp-O--gZxoQPRGTsVgVRdAvpsRTkQI_q8fxADLCe0womFxtvvnD_FJgjaMsm7vkYchXkoq33WWyHijb3JMkymjl0_GtiSamT0qEL6sm_l5Z1lehqBGUEHfYAa0ub8IDx_yqy2R9Nh8Lwzmz4s24sShVxjaNsMBlSE-sEvTziOsnNWK1Zl_XUYadlENkweuIoxYx_lt8XIV71TzjEFuVTd-pXhzVlqePmIu3SM3bO1Kzq_DnGfB62RmzlmbtHU4iyw4Hd1wQFRhTeSRrvMjsMPFKN-SIIQU7CRNaMuaDxZbNZcOKhMg_h9mApM0rRS3VZaGZzFTL9rSaDMYHw4pL3aOkSFPMY3w785Tss7Zqwuo9HFUWUVbnYAb97JkgCohlMotORrMMtual1dQ4sG1sIYXyWTckAGGL0ZAGurhtSKiyz1m8Lb39pXPacqFh_nCHqqb2_RdrKTj0PdGZESKkU8YedeqC1I9nR4v38DuQc-pBBR5DOwgNjJMvzvsUehs_PxIL8THjgIcr7ONc4hWV9o2v_l81Vo2cCW2I99Iz84IFN2fV1dTqHIG_tnLzz8ljBVygETUqrFdZ0JlQJkurZ7RBku5krm-k9CZmDezCIzPPil-RcYzVIk00gNYAxfiZE48Or4WEiGjgKLnHCYVtSlvlMF4bPGB4SVCZ-68j49EjfSWaMK0OoMkpGhqf7KchgxYBZq6o3AhLgp4t0BClvsdee6VTz1SFqc3m2A-TMG6fNdbCT_Q9nYCYdZIROdOc';

    var aes = new sjcl.cipher.aes( prepare_key_pw("oEyoo9cQcw") );
    k = decrypt_key(aes, base64_to_a32(json_k) );

    aes = new sjcl.cipher.aes(k);

    var t = mpi2b(base64urldecode(json_csid));

    var privk = a32_to_str(decrypt_key(aes,base64_to_a32(json_privk)));

    var rsa_privk = Array(4);
    for (var i = 0; i < 4; i++)
    {
        var l = ((privk.charCodeAt(0)*256+privk.charCodeAt(1)+7)>>3)+2;

        rsa_privk[i] = mpi2b(privk.substr(0,l));
        if (typeof rsa_privk[i] == 'number') break;
        privk = privk.substr(l);    
    }

    var p = parseHexString(createHexString(rsa_privk[0]));  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    var q = parseHexString(createHexString(rsa_privk[1]));  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    var d = parseHexString(createHexString(rsa_privk[2]));  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    var u = parseHexString(createHexString(rsa_privk[3]));  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    sid = base64urlencode(b2s(RSAdecrypt(t,d,p,q,u)).substr(0,43));
    if (sid!=='tajetAbW0qTQGFlwp8iD5lQ0TFV1QUZJZFVvjRX7Xx-bPzYBoau7qog09w')
        console.log("ERROR");

    p = rsa_privk[0];
    q = rsa_privk[1];
    d = rsa_privk[2];
    u = rsa_privk[3];
    sid = base64urlencode(b2s(RSAdecrypt(t,d,p,q,u)).substr(0,43));
    if (sid=='tajetAbW0qTQGFlwp8iD5lQ0TFV1QUZJZFVvjRX7Xx-bPzYBoau7qog09w')
        console.log("OK");
}
</script>

</head>
<body onload="t();"></body>
</html>

I am not javascript developer, and not one found in google code did not work on this data.

我不是javascript开发人员,在谷歌代码中没有发现这个数据。

Update 1

更新1

console.log(createHexString(rsa_privk[0])); = e5d109c673d8ef03df564beb9e36e9983a23842b0a724efa45ff76bbe5ad72ed62d2757968 

But if do

但如果做

parseHexString('e5d109c673d8ef03df564beb9e36e9983a23842b0a724efa45ff76bbe5ad72ed‌​62d2757968'); 

then code if (sid!== ... make error

然后代码如果(sid != =…使错误

Update 2

更新2

console.log(rsa_privk[0].toString(16));

output: 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

输出:123676133,198914513,123676133,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

Update 3

更新3

console.log(parseHexString(createHexString(rsa_privk[0])));
console.log(rsa_privk[0]);

output:

输出:

[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]

[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]

5 个解决方案

#1


8  

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].

这将永远不会与rsa_privk[0]相同。

Because, createHexString() only uses the last 2 bytes from each array element.

因为createHexString()只使用每个数组元素的最后2个字节。

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...

这两个函数…hex总是包含8个字节块,每个元素都包含在数组中…

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();
}

#2


19  

Convert a hex string to a byte array and vice versa

将十六进制字符串转换为字节数组,反之亦然。

note: implementation from crypto-js

注意:从crypto-js实现

// Convert a hex string to a byte array
function hexToBytes(hex) {
    for (var bytes = [], 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) {
    for (var hex = [], i = 0; i < bytes.length; i++) {
        hex.push((bytes[i] >>> 4).toString(16));
        hex.push((bytes[i] & 0xF).toString(16));
    }
    return hex.join("");
}

#3


5  

I just wanted to chime in that there is a library at https://github.com/dcodeIO/bytebuffer.js to easily help with conversions like this, and thus you don't need to write your own functions (which could possibly not be the most optimal, or be more optimal if your solution was reviewed through the open source community on GitHub).

我只是想插话,有一个图书馆在https://github.com/dcodeIO/bytebuffer.js上轻松地帮助这样的转换,因此您不需要编写自己的函数(这可能不是最优的,或更优,如果你解决了通过开源社区在GitHub上)。

var ByteBuffer = require("bytebuffer");

var bb = ByteBuffer.fromHex(yourHexString);

// need to convert it to base 64?
// bb.toBase64();

See https://github.com/dcodeIO/bytebuffer.js/wiki/API#bytebufferfromhexstr-littleendian-noassert for the API documention and more insight on the methods I used above.

请参阅https://github.com/dcodeIO/bytebuffer.js/wiki/API#bytebufferfromhexstr-littleendian-noassert的API文档,并对我上面使用的方法有更多的了解。

#4


0  

Here is a live sample for this test.

这是这次测试的现场样本。

http://jsfiddle.net/vincentwang2020/eks1z4g2/

http://jsfiddle.net/vincentwang2020/eks1z4g2/

function testcreateHexString()
{
    alert('test function createHexString');
    var key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
    var result = createHexString(key);
    alert ('Hex value:' + result);

    alert('test function parseHexString');

    var key2 = parseHexString(result);

    if (key.sort().join() == key2.sort().join())
        alert ('Matched');

}

#5


0  

Just to clarify, if you simply want to hex decode a simple string such as 48656C6C6F20576F726C6421 (Hello World!) you can use the OP function but instead of using a length of 8 you should use a length of 2.

只是为了说明,如果你只是想要解码一个简单的字符串,比如48656C6C6F20576F726C6421 (Hello World!),你可以使用OP函数,但是不要使用长度为8的字符串,你应该使用长度为2的函数。

Code:

代码:

var DecodeHexStringToByteArray = function (hexString) {
   var result = [];
   while (hexString.length >= 2) { 
       result.push(parseInt(hexString.substring(0, 2), 16));
       hexString = hexString.substring(2, hexString.length);
   }
   return result;
}

Output will be [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]

输出将是[72,101,108,108,111,32,87,111,114,108,100,33]

I know that this code is already in the OP question, but it's not in the accepted answer. My intent here is only to give a straight answer to the first part of the question being asked (How to convert a hex string into a bytes array).

我知道这段代码已经在OP问题中了,但是它并没有被接受。我的意图只是给出一个问题的第一部分的直接答案(如何将十六进制字符串转换成字节数组)。

#1


8  

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].

这将永远不会与rsa_privk[0]相同。

Because, createHexString() only uses the last 2 bytes from each array element.

因为createHexString()只使用每个数组元素的最后2个字节。

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...

这两个函数…hex总是包含8个字节块,每个元素都包含在数组中…

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();
}

#2


19  

Convert a hex string to a byte array and vice versa

将十六进制字符串转换为字节数组,反之亦然。

note: implementation from crypto-js

注意:从crypto-js实现

// Convert a hex string to a byte array
function hexToBytes(hex) {
    for (var bytes = [], 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) {
    for (var hex = [], i = 0; i < bytes.length; i++) {
        hex.push((bytes[i] >>> 4).toString(16));
        hex.push((bytes[i] & 0xF).toString(16));
    }
    return hex.join("");
}

#3


5  

I just wanted to chime in that there is a library at https://github.com/dcodeIO/bytebuffer.js to easily help with conversions like this, and thus you don't need to write your own functions (which could possibly not be the most optimal, or be more optimal if your solution was reviewed through the open source community on GitHub).

我只是想插话,有一个图书馆在https://github.com/dcodeIO/bytebuffer.js上轻松地帮助这样的转换,因此您不需要编写自己的函数(这可能不是最优的,或更优,如果你解决了通过开源社区在GitHub上)。

var ByteBuffer = require("bytebuffer");

var bb = ByteBuffer.fromHex(yourHexString);

// need to convert it to base 64?
// bb.toBase64();

See https://github.com/dcodeIO/bytebuffer.js/wiki/API#bytebufferfromhexstr-littleendian-noassert for the API documention and more insight on the methods I used above.

请参阅https://github.com/dcodeIO/bytebuffer.js/wiki/API#bytebufferfromhexstr-littleendian-noassert的API文档,并对我上面使用的方法有更多的了解。

#4


0  

Here is a live sample for this test.

这是这次测试的现场样本。

http://jsfiddle.net/vincentwang2020/eks1z4g2/

http://jsfiddle.net/vincentwang2020/eks1z4g2/

function testcreateHexString()
{
    alert('test function createHexString');
    var key = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
    var result = createHexString(key);
    alert ('Hex value:' + result);

    alert('test function parseHexString');

    var key2 = parseHexString(result);

    if (key.sort().join() == key2.sort().join())
        alert ('Matched');

}

#5


0  

Just to clarify, if you simply want to hex decode a simple string such as 48656C6C6F20576F726C6421 (Hello World!) you can use the OP function but instead of using a length of 8 you should use a length of 2.

只是为了说明,如果你只是想要解码一个简单的字符串,比如48656C6C6F20576F726C6421 (Hello World!),你可以使用OP函数,但是不要使用长度为8的字符串,你应该使用长度为2的函数。

Code:

代码:

var DecodeHexStringToByteArray = function (hexString) {
   var result = [];
   while (hexString.length >= 2) { 
       result.push(parseInt(hexString.substring(0, 2), 16));
       hexString = hexString.substring(2, hexString.length);
   }
   return result;
}

Output will be [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]

输出将是[72,101,108,108,111,32,87,111,114,108,100,33]

I know that this code is already in the OP question, but it's not in the accepted answer. My intent here is only to give a straight answer to the first part of the question being asked (How to convert a hex string into a bytes array).

我知道这段代码已经在OP问题中了,但是它并没有被接受。我的意图只是给出一个问题的第一部分的直接答案(如何将十六进制字符串转换成字节数组)。