JavaScript ascii 到 utf-8 的转换问题与负数

JavaScript ascii to utf-8 conversion problems with negatives

本文关键字:问题 转换 ascii utf-8 JavaScript      更新时间:2023-09-26

我正在解密服务器端信息,我的加密以不同的语言工作,因此知道解密应该是什么?

为什么负数不正确,而正数却不正确?

运行示例:

输出格式:

str
pos
S[t]
str.charAt(str, pos + 1)
str.charCodeAt(pos + 1)

根据 GML 解密:

Input:
Str: ���
Key: 472
--------------
str: ���
pos: 0
ST: 195
char: ⮫
value: -94
str: ���
pos: 1
ST: 140
char: 
value: -18
str: ���
pos: 2
ST: 136
char: 
value: -21

服务器端等效项 (JS):

Input: 
Str: ���
Key: 472
---------------
str: ���
pos: 0
ST: 195
char: �
value: 65533
str: ���
pos: 1
ST: 140
char: �
value: 65533
str: ���
pos: 2
ST: 136
char: 
value: NaN

信息如何到达输入:数据从 Server.js -> Client 传递.js其中标头被获取并通过 switch 语句放置,然后使用以下方法解析数据包的其余部分:

var Parser = require('binary-parser').Parser;
login: new Parser().skip(1)
        .string("command", StringOptions)
        .string("username", StringOptions)
        .string("password", StringOptions),

然后输入到方法:console.log(rc4(data.password, c.dhprivatekey));

如果需要,我的代码:

function rc4(str, key) {
    var out = "";
    var len = byteCount(key);
    var S = [], j;
    var t;
    for(var i = 0; i < 256; i++) {
        S[i] = i;
    }
    j = 0;
    for( var i = 0; i< 256; i++) {
        var test = string_byte_at(key, (i % len) + 1)[0];
        if (typeof test != "number") {
        test = parseInt(test);
        }
        j = (j + S[i] + test % 256);
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }
    i = 0;
    j = 0;

    for (var pos = 0; pos < str.length; pos++) {
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;
        var temp = S[i];
        S[i] = S[j];
        S[j] = temp;
        t = (S[i] + S[j]) % 256;
        out += str.charCodeAt(string_byte_at(str, pos + 1)[0] ^ S[t]);
    }
    return out;
    }

在 GML 中正确工作解密

 var str,key,out,len,i,S,j,temp,pos,t;
str = argument0;
key = string(argument1);
out = "";
len = string_byte_length(key);
for (i=0; i<256; i+=1) S[i] = i;
j = 0;
for (i=0; i<256; i+=1) {
    //show_debug_message(string_byte_at(key, (i mod len) + 1));
    j = (j + S[i] + string_byte_at(key,(i mod len)+1)) mod 256;
    temp = S[i];
    S[i] = S[j];
    S[j] = temp;
}
i = 0;
j = 0;
for (pos=0; pos < string_byte_length(str); pos+=1) {
    i = (i + 1) mod 256;
    j = (j + S[i]) mod 256;
    temp = S[i];
    S[i] = S[j];
    S[j] = temp;
    t = (S[i] + S[j]) mod 256;
    out += ansi_char(string_byte_at(str,pos+1) ^ S[t]);
}
return out;

http://docs.yoyogames.com/source/dadiospice/002_reference/strings/string_byte_at.html

http://docs.yoyogames.com/source/dadiospice/002_reference/strings/ansi_char.html

http://gmc.yoyogames.com/index.php?showtopic=554460

我的代码无法正常工作的原因归结为多种原因:客户端和服务器之间的连接输出无符号的 32 位整数,同时尝试输入有符号的 16 位整数,这使得密钥不相等。

一旦这个问题被修复,我得到负数的原因纯粹是因为Game Maker Language和JavaScript之间的差异。

在 JavaScript 中,您可以将字符串与 ascii 相互转换,但是在 gml 中,根据我可以收集的内容,他们将 ascii 与其他符号相结合,以给出从 -256 到 256 的符号范围,如中文、日语和拉丁语,这些符号不包括在 ascii 或 ascii 扩展中。

为了解决我的问题,我必须防止 gml 像这样编码并坚持使用正常的 ascii 字符,这允许我在 JavaScript 中正确读取和解密。