Javascript ArrayBuffer to Hex

后端 未结 9 483
迷失自我
迷失自我 2020-11-30 05:51

I\'ve got a Javascript ArrayBuffer that I would like to be converted into a hex string.

Anyone knows of a function that I can call or a pre written function already

相关标签:
9条回答
  • 2020-11-30 06:02

    Here is another solution which is, on Chrome (and probably node too) about 3x faster than the other suggestions using map and toString:

    function bufferToHex(buffer) {
        var s = '', h = '0123456789ABCDEF';
        (new Uint8Array(buffer)).forEach((v) => { s += h[v >> 4] + h[v & 15]; });
        return s;
    }
    

    Additional bonus: you can easily choose uppercase/lowercase output.

    See bench here: http://jsben.ch/Vjx2V

    0 讨论(0)
  • 2020-11-30 06:04

    In Node, we can use Buffer.from(unitarray, “hex”)

    0 讨论(0)
  • 2020-11-30 06:05

    function buf2hex(buffer) { // buffer is an ArrayBuffer
      return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
    }
    
    // EXAMPLE:
    const buffer = new Uint8Array([ 4, 8, 12, 16 ]).buffer;
    console.log(buf2hex(buffer)); // = 04080c10

    This function works in four steps:

    1. Converts the buffer into an array.
    2. For each x the array, it converts that element to a hex string (e.g., 12 becomes c).
    3. Then it takes that hex string and left pads it with zeros (e.g., c becomes 0c).
    4. Finally, it takes all of the hex values and joins them into a single string.

    Below is another longer implementation that is a little easier to understand, but essentially does the same thing:

    function buf2hex(buffer) { // buffer is an ArrayBuffer
      // create a byte array (Uint8Array) that we can use to read the array buffer
      const byteArray = new Uint8Array(buffer);
      
      // for each element, we want to get its two-digit hexadecimal representation
      const hexParts = [];
      for(let i = 0; i < byteArray.length; i++) {
        // convert value to hexadecimal
        const hex = byteArray[i].toString(16);
        
        // pad with zeros to length 2
        const paddedHex = ('00' + hex).slice(-2);
        
        // push to array
        hexParts.push(paddedHex);
      }
      
      // join all the hex values of the elements into a single string
      return hexParts.join('');
    }
    
    // EXAMPLE:
    const buffer = new Uint8Array([ 4, 8, 12, 16 ]).buffer;
    console.log(buf2hex(buffer)); // = 04080c10

    0 讨论(0)
  • 2020-11-30 06:09

    Here is a sweet ES6 solution, using padStart and avoiding the quite confusing prototype-call-based solution of the accepted answer. It is actually faster as well.

    function bufferToHex (buffer) {
        return [...new Uint8Array (buffer)]
            .map (b => b.toString (16).padStart (2, "0"))
            .join ("");
    }
    

    How this works:

    1. An Array is created from a Uint8Array holding the buffer data. This is so we can modify the array to hold string values later.
    2. All the Array items are mapped to their hex codes and padded with 0 characters.
    3. The array is joined into a full string.
    0 讨论(0)
  • 2020-11-30 06:10

    The simplest way to convert arraybuffer to hex:

    const buffer = new Uint8Array([ 4, 8, 12, 16 ]);
    console.log(Buffer.from(buffer).toString("hex")); // = 04080c10
    
    0 讨论(0)
  • 2020-11-30 06:13

    The following solution uses precomputed lookup tables for both forward and backward conversion.

    // look up tables
    var to_hex_array = [];
    var to_byte_map = {};
    for (var ord=0; ord<=0xff; ord++) {
        var s = ord.toString(16);
        if (s.length < 2) {
            s = "0" + s;
        }
        to_hex_array.push(s);
        to_byte_map[s] = ord;
    }
    
    // converter using lookups
    function bufferToHex2(buffer) {
        var hex_array = [];
        //(new Uint8Array(buffer)).forEach((v) => { hex_array.push(to_hex_array[v]) });
        for (var i=0; i<buffer.length; i++) {
            hex_array.push(to_hex_array[buffer[i]]);
        }
        return hex_array.join('')
    }
    // reverse conversion using lookups
    function hexToBuffer(s) {
        var length2 = s.length;
        if ((length2 % 2) != 0) {
            throw "hex string must have length a multiple of 2";
        }
        var length = length2 / 2;
        var result = new Uint8Array(length);
        for (var i=0; i<length; i++) {
            var i2 = i * 2;
            var b = s.substring(i2, i2 + 2);
            result[i] = to_byte_map[b];
        }
        return result;
    }
    

    This solution is faster than the winner of the previous benchmark: http://jsben.ch/owCk5 tested in both Chrome and Firefox on a Mac laptop. Also see the benchmark code for a test validation function.

    [edit: I change the forEach to a for loop and now it's even faster.]

    0 讨论(0)
提交回复
热议问题