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

问题描述

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

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

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

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

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

  • 我不想查找与我要发送的字节对应的 ASCII 代码

  • 我不想一一索引每个字符,例如data[0] = '/'; data[1] = 'f'; ...

解决方法

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

const message = toMessage(["/","f","o",","i",123,0]);
// or even
const message = toMessage(["/foo",i",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(["/",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]);

console.log(message);

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


或者,如果您要使用的文本字符仅在 7 位 ASCII 可打印范围内,则只有 96 个字符。您可以轻松为他们设置 const

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_COMMA,L_i,0]);

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