美文网首页golang面试
golang实现redis协议之10进制ascii码转义

golang实现redis协议之10进制ascii码转义

作者: realPeanut | 来源:发表于2020-11-02 22:56 被阅读0次
  • 例子: 当执行 get key时 假设 返回 100000000

抓包返回如下

24 39 0d 0a 31 30 30 30 30 30 30 30 30 0d 0a

  • 其中第一个字节24为16进制的ASCII码$

代表批量回复

  • 第二个字节为16进制的ASCII码9

代表value值为9位ASCII码,9字节

  • 0d 0a 代表\r\n
  • 31 30 30 30 30 30 30 30 30 为1、0、0、0、0 0、0、0、0的ASCII码
  • 拼接后即为100000000

以上是分析的抓包数据


  • 在实际开发过程中如下golang程序中,rs得到的实际值是10进制的ASCII码,数据类型为[]byte
    r := bufio.NewReader(rc.Conn.conn)

    p, err := r.ReadSlice(redis_cut)
    ... 
    ln, err := io.ReadFull(r, rs)
[36 57 13 10] [49 48 48 48 48 48 48 48 48]
  • 因为要知道36($)后的57代表的实际字符,而且要转为int,这样我们才能只要要从io.buffer中读取多少字节,所以我们要进行以下操作
  • ascii做算数减法,减去ascii码'0'(ascii 十进制为48)
func ParseLen(p []byte) (int, error) {

fmt.Println(p)
    if len(p) == 0 {

        return -1, nil
    }

    if p[0] == '-' && len(p) == 2 && p[1] == '1' {
        return -1, nil
    }

    var n int
    for _, b := range p {
        n *= 10
        if b < '0' || b > '9' {
            return -1, nil
        }
        n += int(b - '0')
        //ascii运算相当于57-48
    }
  • 总结在我们自己写10进制ascii转码int时,可以用下面的方法
    zjd := make([]byte,2)
    t[0] = 57
    println(t[0] - 48 )//方法1
    println(t[0] - '0' )//方法2

redis数据传输采用的小端法,我们不用过多处理
如果是其他协议采用大端法传输时,需要进行特殊处理。

相关文章

网友评论

    本文标题:golang实现redis协议之10进制ascii码转义

    本文链接:https://www.haomeiwen.com/subject/espvvktx.html