var saltVal = crypto.getRandomValues(new Uint8Array(16));
function arrayBufferToHexString(bytes) {
bytes = new Uint8Array(bytes);
var hex = new Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
hex[i] = ("0" + bytes[i].toString(16)).slice(-2);
}
return hex.join("");
}
function bytesToHexString(bytes) {
bytes = new Uint8Array(bytes);
var hexBytes = [];
for (var i = 0; i < bytes.length; i++) {
var byteString = bytes[i].toString(16);
if (byteString.length < 2) byteString = "0" + byteString;
hexBytes.push(byteString);
}
return hexBytes.join("");
}
function buf2hex(buffer) { // buffer is an ArrayBuffer
return [new Uint8Array(buffer)]
.map(x => x.toString(16).padStart(2, '0'))
.join('');
}
function hex(arrayBuffer)
{
const asciiCodes = new Uint8Array(
Array.prototype.map.call(
"0123456789abcdef",
char => char.charCodeAt()
)
);
const buff = new Uint8Array(arrayBuffer);
const charCodes = new Uint8Array(buff.length * 2);
for (let i = 0; i < buff.length; ++i)
{
charCodes[i * 2] = asciiCodes[buff[i] >>> 4];
charCodes[i * 2 + 1] = asciiCodes[buff[i] & 0xf];
}
return String.fromCharCode(charCodes);
}
function hex2(arrayBuffer)
{
return Array.prototype.map.call(
new Uint8Array(arrayBuffer),
n => n.toString(16).padStart(2, "0")
).join("");
}
function arrayBufferToBase64(buffer) {
const byteArray = new Uint8Array(buffer);
const binaryString = byteArray.reduce((acc, byte) => acc + String.fromCharCode(byte), "");
return btoa(binaryString);
}
function arrayBufferToBase64loop( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
}
arrayBufferToHexString(saltVal);
bytesToHexString(saltVal)
buf2hex(saltVal)
hex(saltVal)
hex2(saltVal)
arrayBufferToBase64(saltVal)
arrayBufferToBase64loop(saltVal)
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
directly set | |
push values | |
buf2hex() | |
precomputed ASCII with shift | |
array prototype map | |
base64 | |
base64 loop |
Test name | Executions per second |
---|---|
directly set | 2518190.2 Ops/sec |
push values | 3320277.8 Ops/sec |
buf2hex() | 1633906.6 Ops/sec |
precomputed ASCII with shift | 861667.0 Ops/sec |
array prototype map | 1007366.4 Ops/sec |
base64 | 3442614.0 Ops/sec |
base64 loop | 4389549.5 Ops/sec |
The benchmark conducted on MeasureThat.net focuses on performance comparisons for converting an ArrayBuffer
to two different formats: hexadecimal (hex) and base64. It includes five different methods for converting ArrayBuffer
to hex and two methods for base64 conversion. Here's a breakdown of the tested methods, their pros and cons, and other considerations:
arrayBufferToHexString
ArrayBuffer
to hex format by directly accessing and converting each byte.bytesToHexString
arrayBufferToHexString
, but uses an intermediate array to push values.buf2hex
Uint8Array
, mapping each byte to hex.hex
hex2
Array.prototype.map
method to convert each byte to hex and join into a string.arrayBufferToBase64
ArrayBuffer
to a binary string and then encodes it to base64 using btoa
.arrayBufferToBase64loop
ArrayBuffer
and encodes it to base64 using btoa
.From the benchmark results, the following observations can be made:
Other alternatives for converting ArrayBuffer
to hex or base64 could include:
buffer
in Node.js that offer optimized methods for conversions.TextEncoder
and TextDecoder
to handle conversions if encoding and decoding strings are necessary.Overall, the choice of method depends on the specific constraints of the project, including performance requirements relative to memory usage and code maintainability.