strconv.Unquote 函数跟踪

您所在的位置:网站首页 switch串流教程 strconv.Unquote 函数跟踪

strconv.Unquote 函数跟踪

#strconv.Unquote 函数跟踪| 来源: 网络整理| 查看: 265

前言:在做扫描的时候有一些探测是要发送一些字节和数据流才可以识别,这时候就需要针对一些字符串做一些解释,达到数据流这些字符。

需要的转的字符 #原值 \x41\x00\x00\x00\x3a\x30\x00\x00 #发送时候的数据 A:0 在go的代码里使用双引号 str := "\x41\x00\x00\x00\x3a\x30\x00\x00" log.Print(str) #结果正常 A:0 使用反引号 str := `\x41\x00\x00\x00\x3a\x30\x00\x00` log.Print(str) #结果 \x41\x00\x00\x00\x3a\x30\x00\x00 双引号,单引号,反引号 双引号,会自动解析 \t \n \r \x \uxxx \U 这些特殊的字符 单引号,只能放一个字符 'a' 'b'' '1' 反引号,不会解析任何特殊标记,可以适用于大量文本的情况下,建议使用; 但是反引号因为不转义,需求又想要这样的解析特殊字符,这时候怎么操作? strconv.Unquote 函数跟踪 strconv.Unquote 反解析函数,当内容如:`"\t\n"` 那么就会自动进行解析双引号里的内容,达到和双引号直接引入的效果。那么具体怎么实现的呢? 方法源码 (加注释和解释): func Unquote(s string) (string, error) { n := len(s) if n < 2 { return "", ErrSyntax } quote := s[0] // 本步骤是判断第一个字符和最后一个字符是否相等,如果相等,向下走,也就是 "xxxxxxx" if quote != s[n-1] { return "", ErrSyntax } s = s[1 : n-1] // 判断标记是不是 反引号开始 if quote == '`' { if contains(s, '`') { return "", ErrSyntax } if contains(s, '\r') { // -1 because we know there is at least one \r to remove. buf := make([] byte , 0, len(s)-1) for i := 0; i < len(s); i++ { if s[i] != '\r' { buf = append(buf, s[i]) } } return string(buf), nil } return s, nil } // 这个过程是为了确定,是不是以 双引号或者单引号 开始 if quote != '"' && quote != '\'' { return "", ErrSyntax } // 如果双引号内容有回车,那么调用该方法直接就会失败 if contains(s, '\n') { return "", ErrSyntax } // Is it trivial? Avoid allocation. if !contains(s, '\\') && !contains(s, quote) { switch quote { case '"': if utf8.ValidString(s) { return s, nil } case '\'': r, size := utf8.DecodeRuneInString(s) if size == len(s) && (r != utf8.RuneError || size != 1) { return s, nil } } } // 开始到解析的过程了 var runeTmp [utf8.UTFMax]byte buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations. for len(s) > 0 { // 核心解析方法 会进入到 UnquoteChar 方法详细解析 c 就是本次解析返回的结果 c, multibyte, ss, err := UnquoteChar(s, quote) if err != nil { return "", err } s = ss if c < utf8.RuneSelf || !multibyte { buf = append(buf, byte(c)) } else { n := utf8.EncodeRune(runeTmp[:], c) buf = append(buf, runeTmp[:n]...) } if quote == '\'' && len(s) != 0 { // single-quoted must be single character return "", ErrSyntax } } return string(buf), nil } func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) { // easy cases if len(s) == 0 { err = ErrSyntax return } //取出字符串的第一位 判断是否相等,如果相等就直接返回了 switch c := s[0]; { case c == quote && (quote == '\'' || quote == '"'): err = ErrSyntax return case c >= utf8.RuneSelf: r, size := utf8.DecodeRuneInString(s) return r, true, s[size:], nil case c != '\\': return rune(s[0]), false, s[1:], nil } // hard case: c is backslash if len(s)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3