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

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

  •  
  •   chensuixiang · 2023-08-26 11:06:25 +08:00 · 2471 次点击
    这是一个创建于 445 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    没太大区别的,不用去纠结这玩意它看起来像不像或者是不是字符串。
    dode
        16
    dode  
       2023-08-26 16:52:27 +08:00
    @hsfzxjy 所以这个系统后台是不是 python 呢
    hsfzxjy
        17
    hsfzxjy  
       2023-08-26 17:08:40 +08:00 via Android
    @dode 嗯?为啥问我是不是 python 。这个帖子里好像没提到过
    chensuixiang
        18
    chensuixiang  
    OP
       2023-08-26 17:37:24 +08:00
    @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
       2023-08-26 17:38:05 +08:00
    @yolee599 顺带艾特这个大佬,请教大佬
    maybeonly
        20
    maybeonly  
       2023-08-26 17:48:28 +08:00
    https://www.rfc-editor.org/rfc/rfc6455
    看文档。不要 base64 ,完全是副作用。
    看起来你没有发送一个完整的帧,而且前半个不知道是什么东西。调试 ws 的话最好从握手结束就开始,因为每个 frame 或者 msg 有长度。
    hsfzxjy
        21
    hsfzxjy  
       2023-08-26 20:47:15 +08:00 via Android
    建议你去看 base64 的定义,简单说是原文三个字节会对应 base64 四个字节,你直接看他的实现就懂了
    hsfzxjy
        22
    hsfzxjy  
       2023-08-26 20:48:37 +08:00 via Android
    你这也不只变了个 3 啊,第一行不是全变了吗。该不会觉得所有的点...都是一样的吧
    g1f9
        23
    g1f9  
       2023-08-26 20:52:04 +08:00
    哪款在线文档
    xiwh
        24
    xiwh  
       2023-08-26 21:48:35 +08:00
    用二进制包的角度分析,看起来不难,前两字节应该是包类型(0x0002 为文本或者 error?), 第三个和第四个字节一看就是包长度 0x0008 ,正好对应后续字符所占字节数量
    chensuixiang
        25
    chensuixiang  
    OP
       2023-08-26 23:26:14 +08:00
    @hsfzxjy 我有试了很多次,同一个数字的,没描述清。比如都是发 4
    ```
    00000001: 0200 0134 00 ...4.

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

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