Binary to hex

Benchmark created on


Setup

// @ts-check

/**
 *
 * @param {string} hex
 * @returns {Uint8Array}
 */
function h2b_efficient(hex) {
  const binary = new Uint8Array(hex.length >> 1);
  /**
   * @type {number}
   */
  let char;

  for (let i = 0; i < hex.length; i++) {
    char = hex.charCodeAt(i);

    if (char >= 48 && char <= 57) {
      char -= 48;
    } else if (char >= 65 && char <= 70) {
      char -= 55;
    } else if (char >= 97 && char <= 102) {
      char -= 87;
    } else {
      throw new Error(`Invalid hex character: "${hex[i]}"`);
    }

    if (i & 1) {
      binary[i >> 1] <<= 4;
      binary[i >> 1] |= char;
    } else {
      binary[i >> 1] = char;
    }
  }

  return binary;
}

/**
 *
 * @param {number} value
 * @returns
 */
function hex_switch(value) {
  switch (value) {
    case 0:
      return "0";
    case 1:
      return "1";
    case 2:
      return "2";
    case 3:
      return "3";
    case 4:
      return "4";
    case 5:
      return "5";
    case 6:
      return "6";
    case 7:
      return "7";
    case 8:
      return "8";
    case 9:
      return "9";
    case 10:
      return "a";
    case 11:
      return "b";
    case 12:
      return "c";
    case 13:
      return "d";
    case 14:
      return "e";
    case 15:
      return "f";
   
  }
}

/**
 *
 * @param {number} value
 * @returns
 */
function hex_str_add(value) {
  if (value < 10) {
    return String.fromCharCode(value + 48);
  } else {
    return String.fromCharCode(value + 87);
  }
}

const map = new Map([
  [0, "0"],
  [1, "1"],
  [2, "2"],
  [3, "3"],
  [4, "4"],
  [5, "5"],
  [6, "6"],
  [7, "7"],
  [8, "8"],
  [9, "9"],
  [10, "a"],
  [11, "b"],
  [12, "c"],
  [13, "d"],
  [14, "e"],
  [15, "f"]
]);

/**
 *
 * @param {number} value
 * @returns
 */
function hex_map_search(value) {
  return map.get(value);
}

/**
 * @type {Record<number, string>}
 */
const object = {
  0: "0",
  1: "1",
  2: "2",
  3: "3",
  4: "4",
  5: "5",
  6: "6",
  7: "7",
  8: "8",
  9: "9",
  10: "a",
  11: "b",
  12: "c",
  13: "d",
  14: "e",
  15: "f"
};

/**
 *
 * @param {number} value
 * @returns
 */
function hex_object_search(value) {
  return object[value];
}

const array = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']

/**
 * 
 * @param value 
 * @returns 
 */
function hex_arr_index(value) {
  return array[value];
}

const hexChars = '0123456789abcdef';

/**
 * 
 * @param value 
 * @returns 
 */
function hex_str_index(value) {
  return hexChars[value];
}

/**
 *
 * @param {Uint8Array} bytes
 * @param {(value: number) => string} valueToChar
 * @returns {string}
 */
function b2h_efficient(bytes, valueToChar = hex_str_add) {
  let result = "";

  for (let i = 0; i < bytes.length; i++) {
    result += valueToChar(bytes[i] >> 4);
    result += valueToChar(bytes[i] & 0xf);
  }

  return result;
}


const bytes = new Uint8Array([0xC0, 0xFF, 0xEE]);

Test runner

Ready to run.

Testing in
TestOps/sec
Hex switch
b2h_efficient(bytes, hex_switch) === 'c0ffee' 
ready
Hex String.fromCharCodes
b2h_efficient(bytes, hex_str_add) === 'c0ffee'
ready
Hex map search
b2h_efficient(bytes, hex_map_search) === 'c0ffee' 
ready
Hex object search
b2h_efficient(bytes, hex_object_search) === 'c0ffee'
ready
Hex array index
b2h_efficient(bytes, hex_arr_index) === 'c0ffee'
ready
Hex string index
b2h_efficient(bytes, hex_str_index) === 'c0ffee'
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.