How to build a UCS-2 encoded HEX string from a Javascript "basic" string, but only using web api (browser or Deno) features ?
In other words, how to convert the following node code but for the browser ?
message = "hello world 😃"
const buf_le = Buffer.from(message, "ucs2"); // 'ucs2' is as same as 'utf16le'
let buf = Buffer.alloc(buf_le.length); // convert to utf16be (ucs2)
for (let i = 0; i < buf.length; i += 2)
buf.writeUInt16BE(buf_le.readUInt16LE(i), i);
hex = buf.toString("hex");
It will be used to encode text to PDU for SMS sendings.
Thanks!
You can use this solution from How to convert ArrayBuffer to and from String - Chrome Developers (usage of var
updated to use const
or let
):
function str2ab(str) {
const buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
const bufView = new Uint16Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
It uses a Uint16Array
as the view into the ArrayBuffer
. "The Uint16Array
typed array represents an array of 16-bit unsigned integers in the platform byte order. If control over byte order is needed, use DataView
instead."
To get a hex representation there are several options:
view the buf
using a Uint16Array
instance so that you don't need to concern yourself with your platform's byte order:
function uint16Array2hex(array) {
return Array.from(array, (b) => b.toString(16).padStart(4, "0")).join("");
}
update str2ab
to use a DataView
instead of Uint16Array
so that you can write directly to network byte order (big endian):
function str2ab(str) {
const buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
const bufView = new DataView(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView.setUint16(2 * i, str.charCodeAt(i));
}
return buf;
}
function buf2hex(buf) {
const bufView = new Uint8Array(buf);
return Array.from(bufView, (b) => b.toString(16).padStart(2, "0")).join("");
}
Keep str2ab
as-is from Chrome Developers and then convert from platform endianness to big-endian by reading from the buf
using Uint16Array
and writing to a buffer using a DataView
like seen above.