像在 C 中一样从字符和字节值初始化 ArrayData

Initializing ArrayData from characters and byte values as in C

我必须实现一个应该通过 WebSockets 的二进制协议。

在 C 中,我会编写测试数据,例如:

const char test_message[16] = { '/', 'f', 'o', 'o', 0, 0, 0, 0, ',', 'i', 0, 0, 123, 0, 0, 0 };

(这是我正在实施的协议中的有效消息)。

如何以最简单的方式(对于程序员)生成包含相同字节的 JavaScript ArrayData?

假设你想以 Uint8Array 或类似的结尾,并假设你将使用的唯一文本字符是 ASCII,你可以这样做:

const message = toMessage(["/", "f", "o", "o", 0, 0, 0, 0, ",", "i", 0, 0, 123, 0, 0, 0]);
// or even
const message = toMessage(["/foo", 0, 0, 0, 0, ",i", 0, 0, 123, 0, 0, 0]);

对于第一个,toMessage 可能是:

function toMessage(source) {
    const array = new Uint8Array(source.length);
    source.forEach((element, index) => {
        array[index] = typeof element === "string" ? element.charCodeAt(0) : element;
    });
    return array;
}

实例:

function toMessage(source) {
    const array = new Uint8Array(source.length);
    source.forEach((element, index) => {
        array[index] = typeof element === "string" ? element.charCodeAt(0) : element;
    });
    return array;
}

const message = toMessage(["/", "f", "o", "o", 0, 0, 0, 0, ",", "i", 0, 0, 123, 0, 0, 0]);

console.log(message);

如果您想要第二个可以让您将简单字符作为字符串运行的程序,稍微复杂一些。

function toMessage(source) {
    let length = 0;
    for (const element of source) {
        length += typeof element === "string" ? element.length : 1;
    }
    const array = new Uint8Array(length);
    let index = 0;
    for (const element of source) {
        if (typeof element === "string") {
            for (const ch of element) {
                array[index++] = ch.charCodeAt(0);
            }
        } else {
            array[index++] = element;
        }
    }
    source.forEach((element, index) => {
    });
    return array;
}

实例:

function toMessage(source) {
    let length = 0;
    for (const element of source) {
        length += typeof element === "string" ? element.length : 1;
    }
    const array = new Uint8Array(length);
    let index = 0;
    for (const element of source) {
        if (typeof element === "string") {
            for (const ch of element) {
                array[index++] = ch.charCodeAt(0);
            }
        } else {
            array[index++] = element;
        }
    }
    source.forEach((element, index) => {
    });
    return array;
}

const message = toMessage(["/foo", 0, 0, 0, 0, ",i", 0, 0, 123, 0, 0, 0]);

console.log(message);

这些都是现成的,可以在必要时进行优化,或者进行调整以产生 Uint8Array 以外的东西,但是给你想法。


或者,如果您要使用的文本字符正好在 7 位 ASCII 可打印范围内,则只有 96 个字符。你可以轻松地为他们获得 consts:

const L_a = 65;
const L_b = 66;
// ...
const L_A = 97;
const L_B = 98;
// ...

(列表很容易生成,您不必输入。)

那么你根本不需要函数:

const message = UInt8Array.of([L_SLASH, L_f, L_o, L_o, 0, 0, 0, 0, L_COMMA, L_i, 0, 0, 123, 0, 0, 0]);

类型化数组没有文字形式,因此涉及函数调用。