V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chensuixiang
V2EX  ›  程序员

请教 websocket 二进制消息编码问题

  •  
  •   chensuixiang · 245 天前 · 2256 次点击
    这是一个创建于 245 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个协同文档,进入文档后 ws 链接,然后发送与接受文件。浏览器控制台 hex 查看器查看某个消息结果如下

    00000000: 0200 086e 6f20 746f 6b65 6e              ...no token
    

    改用 base64 查看如下

    AgAIbm8gdG9rZW4=
    

    将这个 base64 数据拿到在线 base64 编码解码网站,得到的结果也是...no token

    但是复制到 vscode 中,却是一个 unicode 字符,显示如下(可能显示不正确,建议老哥们随便找个 base64 解码网址看看比如 https://base64.us/ ,显示的是几个类似麻将白板的形状):

      no token
    

    询问 gpt ,什么样的字符串 base64 之后是 AgAIbm8gdG9rZW4=,但是未能解决我的问题。

    问题如下:

    如何手动定义一个字符串变量,base64 编码之后是AgAIbm8gdG9rZW4=

    我尝试过的如下,结果均不对。还请有经验的老哥们指点一下方向

    mes := "\u0002\u0008no token"
    mes2 := "  no token"
    mes2 := "...no token"
    
    
    第 1 条附言  ·  245 天前
    感谢各位老哥的智慧。目前已经搞明白了,正在加紧补充知识点。再次感谢。
    25 条回复    2023-08-26 23:26:14 +08:00
    yolee599
        1
    yolee599  
       245 天前 via Android
    base64 编码的是二进制数据,不一定是字符串
    sujin190
        2
    sujin190  
       245 天前 via Android   ❤️ 1
    二进制编码,前两个字节应该是结果 code ,3 和 4 字节显然是后面错误消息的长度值,你非要把它弄成字符串当然会出现乱码了
    chensuixiang
        3
    chensuixiang  
    OP
       245 天前
    @sujin190 是的, 我查过是结果 code ,STX 这种表示开始结束这些。no token 可以正确转为 bm8gdG9rZW4=,那关于这些结果 code ,怎么变为这个 AgAI 的,老哥清楚不。实在不行如果这个 STX 是固定的,我也可以用这个 AgAI 来组合也能行得通
    chensuixiang
        4
    chensuixiang  
    OP
       245 天前
    目前是确认过结果 code 的,因为复制到 vscode 中就是显示为 STXEOT ,因此也查过了这个表示啥意思。不过发消息过去必须发`AgAIbm8gdG9rZW4=`服务端才能正确接手,所以我有些迷惑如何根据字符串`no token`以及开始结果 code`STXEOT`组合成这个 base64 。而且不止`STXEOT`,还有其他结束 code 。我正在积极查找资料中。如果有经验的老哥,还望指点一下。
    yolee599
        5
    yolee599  
       245 天前 via Android   ❤️ 1
    "\x02\x00\x08no token"
    chensuixiang
        6
    chensuixiang  
    OP
       245 天前
    正在尝试通过 `stx := byte(2)`这种方式。。慢慢查~~
    chensuixiang
        7
    chensuixiang  
    OP
       245 天前
    @yolee599 感谢老哥,刚才查明白了
    ```
    STX (Start of Text):\x02
    ETX (End of Text):\x03
    ENQ (Enquiry):\x05
    ```
    我用这些来组合就行了
    Nazz
        8
    Nazz  
       245 天前 via Android
    go 标准库里有 4 种 base64 编码模式
    hsfzxjy
        9
    hsfzxjy  
       245 天前 via Android   ❤️ 1
    console.log(btoa('\u0002\u0000\u0008no token'))

    楼主可能要补一些底层知识。。
    chensuixiang
        10
    chensuixiang  
    OP
       245 天前
    @hsfzxjy 是的老哥,底层很差。感谢老哥答复,这次又增加了一个知识点了
    Nazz
        11
    Nazz  
       245 天前 via Android
    base64 urlencoding
    chensuixiang
        12
    chensuixiang  
    OP
       245 天前
    @hsfzxjy mes := "\u0002\u0008no token" 我之前有试过,可能糊涂了,居然少了个空格\u0000 。那会已经了解到了这些标识符。再次感谢老哥啊啊啊啊啊,一点我就通了。抱拳了!
    hsfzxjy
        13
    hsfzxjy  
       245 天前 via Android
    你也可以观察你抓到的前三个字节 02 00 08 ,把他们前面都补上\u00 就好了
    maokabc
        14
    maokabc  
       245 天前 via Android
    就不应该把它当文本,直接 16 进制分析就行,别老拿字符串去套,也别管什么控制字符。
    这消息头一个字节应该是 tag 之类表示消息类型,后面应该类似 java 的 writeUTF 写入的字符串(两字节长度加 utf8 编码的文本内容)。
    flyqie
        15
    flyqie  
       245 天前
    遇事不决直接 16 进制怼。

    反正你字符串最后不也是 16 进制?

    没太大区别的,不用去纠结这玩意它看起来像不像或者是不是字符串。
    dode
        16
    dode  
       245 天前
    @hsfzxjy 所以这个系统后台是不是 python 呢
    hsfzxjy
        17
    hsfzxjy  
       245 天前 via Android
    @dode 嗯?为啥问我是不是 python 。这个帖子里好像没提到过
    chensuixiang
        18
    chensuixiang  
    OP
       245 天前
    @hsfzxjy 大佬再请教一下,我通过实验,第一行写数字 4 ,或者换个数字 3 ,发现结果总是中间有差异
    ```
    写 4 的时候是
    AAISAQ GwspbTDgCE5NbfigI AATQA
    00000000: 0002 1201 01b0 b296 d30e 0084 e4d6 df8a ................
    00000001: 0200 0134 00 ...4.


    写 3 的时候是这样的
    AAISAQ HC4KPuCgCEsLKW0w4 AATMA
    00000000: 0002 1201 01c2 e0a3 ee0a 0084 b0b2 96d3 ................
    00000001: 0e00 0133 00 ...3.
    ```
    我感觉我就看懂了一半不到,0002 12 这个对应 AAISAQ 能明白 0133 00 这个也能明白。中间那串 GwspbTDgCE5NbfigI
    就有点看不明白了。比如 01 01b0 b296 d30e 0084 e4d6 df8a 我可以 01 照 ASCII 表对,但是后面的 b0 b296 就看不明白了,一直在变化。这点感觉像是某些类似于时间戳这样子来转换的? 大佬有空赏个脸,没空也没事~~
    chensuixiang
        19
    chensuixiang  
    OP
       245 天前
    @yolee599 顺带艾特这个大佬,请教大佬
    maybeonly
        20
    maybeonly  
       245 天前
    https://www.rfc-editor.org/rfc/rfc6455
    看文档。不要 base64 ,完全是副作用。
    看起来你没有发送一个完整的帧,而且前半个不知道是什么东西。调试 ws 的话最好从握手结束就开始,因为每个 frame 或者 msg 有长度。
    hsfzxjy
        21
    hsfzxjy  
       245 天前 via Android
    建议你去看 base64 的定义,简单说是原文三个字节会对应 base64 四个字节,你直接看他的实现就懂了
    hsfzxjy
        22
    hsfzxjy  
       245 天前 via Android
    你这也不只变了个 3 啊,第一行不是全变了吗。该不会觉得所有的点...都是一样的吧
    g1f9
        23
    g1f9  
       245 天前
    哪款在线文档
    xiwh
        24
    xiwh  
       245 天前
    用二进制包的角度分析,看起来不难,前两字节应该是包类型(0x0002 为文本或者 error?), 第三个和第四个字节一看就是包长度 0x0008 ,正好对应后续字符所占字节数量
    chensuixiang
        25
    chensuixiang  
    OP
       245 天前
    @hsfzxjy 我有试了很多次,同一个数字的,没描述清。比如都是发 4
    ```
    00000001: 0200 0134 00 ...4.

    除了 0134 00 是固定的(应该就是表示 STX 4 END ),前面的 0200 总是会变化,所以我就好奇前面这个 0200 是根据什么来的,为何会一直变化。有时候又变成下面找这个。
    00000001: 0300 0134 00
    ```
    所有的点点点肯定不是同一个的,这个我明白的。

    感谢楼上几位老哥的回复。目前已经实现能更改标题,我的目标其实算完成了。剩下的就是好奇心在作祟。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   878 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 20:31 · PVG 04:31 · LAX 13:31 · JFK 16:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.