如何将字符串编码/解码为gson

时间:2017-11-23 11:39:25

标签: json go character-encoding

我需要使用gson格式(它是json方言)对字符串进行解码和编码。以下是我提出的代码gson(Java) library  由于某些原因,我尝试解码/替换的所有字符实际上都没有被替换。我相信我在逃避角色时遇到了一些问题(我是新手)所以任何方向/帮助来解决它都会受到赞赏。
 Go Playground

 package main

import (
    "bytes"

    "fmt"
    "strings"
)

const s = `https:\/\/exampple.com\/static\/_\/js\/k\x3dgaia.gaiafe_glif.en.nnMHsIffkD4.O\/m\x3dglifb,identifier,unknownerror\/am\x3dggIgAAAAAAEKBCEImA2CYiCxoQo\/rt\x3dj\/d\x3d1\/rs\x3dABkqax3Fc8CWFtgWOYXlvHJI_bE3oVSwgA`
const des = `https://exampple.com/static/_/js/k=gaia.gaiafe_glif.en.nnMHsIffkD4.O/m=P9M9H,HUb4Ab,sy1m,sy1n,emo,sy1k,sy54,gsfs7c/am=ggIgAAAAAAEKBCEImA2CYiCxoQo/rt=j/d=0/rs=ABkqax3Fc8CWFtgWOYXlvHJI_bE3oVSwgA`

func main() {
    dec, err := Decode(s, true)
    if err != nil {
        panic(err)
    }
    if dec != des {
        fmt.Printf("expected \n %v \ngot \n %s", dec, des)
    }
}

type replacementChar map[rune]string

func (r replacementChar) get(k rune) string {
    return fmt.Sprintf("\\u%04x", r[k])
}

var replacement = replacementChar{
    '"':  "\\\"",
    '\\': "\\\\",
    '\t': "\\t",
    '\b': "\\b",
    '\n': "\\n",
    '\r': "\\r",
    '\f': "\\f",
}
var htmlReplacement = replacementChar{
    '<':  "\\u003c",
    '>':  "\\u003e",
    '&':  "\\u0026",
    '=':  "\\u003d",
    '\'': "\\u0027",
}

var extraReplacement = replacementChar{
    '\u2028': "\\u2028",
    '\u2029': "\\u2029",
}

/*
 * From RFC 7159, "All Unicode characters may be placed within the
 * quotation marks except for the characters that must be escaped:
 * quotation mark, reverse solidus, and the control characters
 * (U+0000 through U+001F)."
 *
 * We also escape '\u2028' and '\u2029', which JavaScript interprets as
 * newline characters. This prevents eval() from failing with a syntax
 * error. http://code.google.com/p/google-gson/issues/detail?id=341
 */

func Encode(s string, htmlSafe bool) (string, error) {
    buf := bytes.NewBuffer([]byte("\""))
    var err error
    for _, r := range s {
        switch {
        case replacement[r] != "":
            _, err = buf.WriteString(replacement.get(r))
            if err != nil {
                return "", err

            }
        case htmlSafe && htmlReplacement[r] != "":
            _, err = buf.WriteString(htmlReplacement.get(r))
            if err != nil {
                return "", err

            }
        case extraReplacement[r] != "":
            _, err = buf.WriteString(extraReplacement.get(r))
            if err != nil {
                return "", err

            }
        default:
            _, err = buf.WriteRune(r)
            if err != nil {
                return "", err

            }
        }
    }
    buf.WriteString("\"")
    return buf.String(), nil
}

var decodeHTMLReplacementPair []string
var decodeReplacementPair []string
var decodeReplacementAll []string

func init() {
    for k, _ := range htmlReplacement {
        decodeHTMLReplacementPair = append(decodeHTMLReplacementPair, htmlReplacement.get(k))
        decodeHTMLReplacementPair = append(decodeHTMLReplacementPair, string(k))

    }
    for k, _ := range replacement {
        decodeReplacementPair = append(decodeReplacementPair, replacement.get(k))
        decodeReplacementPair = append(decodeReplacementPair, string(k))

    }
    for k, _ := range extraReplacement {
        decodeReplacementPair = append(decodeReplacementPair, extraReplacement.get(k))
        decodeReplacementPair = append(decodeReplacementPair, string(k))

        decodeHTMLReplacementPair = append(decodeHTMLReplacementPair, extraReplacement.get(k))
        decodeHTMLReplacementPair = append(decodeHTMLReplacementPair, string(k))

    }
    decodeReplacementAll = append(decodeHTMLReplacementPair, decodeReplacementPair...)

}

func Decode(s string, htmlSafe bool) (string, error) {
    var r *strings.Replacer
    if !htmlSafe {
        r = strings.NewReplacer(decodeHTMLReplacementPair...)
    } else {
        r = strings.NewReplacer(decodeReplacementAll...)
    }

    return r.Replace(s), nil
}

/* Original Java Source https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/stream/JsonWriter.java
  private static final String[] REPLACEMENT_CHARS;
  private static final String[] HTML_SAFE_REPLACEMENT_CHARS;
  static {
    REPLACEMENT_CHARS = new String[128];
    for (int i = 0; i <= 0x1f; i++) {
      REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int) i);
    }
    REPLACEMENT_CHARS['"'] = "\\\"";
    REPLACEMENT_CHARS['\\'] = "\\\\";
    REPLACEMENT_CHARS['\t'] = "\\t";
    REPLACEMENT_CHARS['\b'] = "\\b";
    REPLACEMENT_CHARS['\n'] = "\\n";
    REPLACEMENT_CHARS['\r'] = "\\r";
    REPLACEMENT_CHARS['\f'] = "\\f";
    HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
    HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c";
    HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e";
    HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026";
    HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d";
    HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
}


private void string(String value) throws IOException {
    String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
    out.write("\"");
    int last = 0;
    int length = value.length();
    for (int i = 0; i < length; i++) {
      char c = value.charAt(i);
      String replacement;
      if (c < 128) {
        replacement = replacements[c];
        if (replacement == null) {
          continue;
        }
      } else if (c == '\u2028') {
        replacement = "\\u2028";
      } else if (c == '\u2029') {
        replacement = "\\u2029";
      } else {
        continue;
      }
      if (last < i) {
        out.write(value, last, i - last);
      }
      out.write(replacement);
      last = i + 1;
    }
    if (last < length) {
      out.write(value, last, length - last);
    }
    out.write("\"");
}

*/

0 个答案:

没有答案