結論
(1) 16進数文字列変換
const uint8Array = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);
const hexString = Buffer.from(uint8Array).toString("hex"); // "0001fdfeff"
const arrayFromhexString = Uint8Array.from(Buffer.from(hexString, "hex"));
(2) base64変換
const uint8Array = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);
const b64String = Buffer.from(uint8Array).toString("base64"); // "AAH9/v8="
const arrayFronB64String = Uint8Array.from(Buffer.from(b64String, "base64"))
経緯
プロパティにUint8Arrayを持つオブジェクトのシリアライズ・デシリアライズの問題
Uint8Arrayをプロパティに持つオブジェクトをJSON.stringify()
でシリアライズすると、以下のようなJSON文字列に変換されます。
const arr = Uint8Array.from(Array(10).fill(0));
const ob = { uint8array: arr }
const json_str = JSON.stringify(ob);
console.log(json_str)
// {"uint8array":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0}}
このJSON文字列をDBに保存して、後でJSON.parse()
で復元した場合、プロパティの値をそのままUint8Arrayとして扱うことができません。
const json = JSON.parse(json_str);
console.log(json.uint8array)
//{ '0': 0,
// '1': 0,
// '2': 0,
// '3': 0,
// '4': 0,
// '5': 0,
// '6': 0,
// '7': 0,
// '8': 0,
// '9': 0 }
対策として、以下の方法が考えられます。
- (1) DB格納時には16進数文字列として保存、Node.js上ではUint8Arrayとして扱う。
- (2) DB格納時にはbase64変換した文字列として保存、Node.js上ではUint8Arrayとして扱う。
16進数文字列 ⇔ Uint8Array
const arr = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);
const hex = Buffer.from(arr).toString("hex");
console.log(hex)
// 0001fdfeff
const buf_arr = Uint8Array.from(Buffer.from(hex, "hex"))
console.log(buf_arr)
// Uint8Array [ 0, 1, 253, 254, 255 ]
Base64文字列 ⇔ Uint8Array
const arr = Uint8Array.from([0x00, 0x01, 0xfd, 0xfe, 0xff]);
const hex = Buffer.from(arr).toString("base64");
console.log(hex)
// AAH9/v8=
const buf_arr = Uint8Array.from(Buffer.from(hex, "base64"))
console.log(buf_arr)
// Uint8Array [ 0, 1, 253, 254, 255 ]