protoc --decode 使用的二进制到文本编码是什么?

问题描述 投票:0回答:1

我正在查看 protoc --decode 命令的输出,但我无法理解它遇到字节时使用的编码:

data {
  image: "\377\330\377\340\000\020JFIF\000\001[…]\242\2634G\377\331"
}

[…] 是我为了缩短输出而添加的。

这是什么编码?

编辑

因此,根据 Bruce 的回答,我编写了自己的实用程序,以便从 shell 脚本生成示例数据:

public static void main(String[] parameters) throws IOException {
    File binaryInput = new File(parameters[0]);
    System.out.println("\""+TextFormat.escapeBytes(ByteString.readFrom(new FileInputStream(binaryInput)))+"\"");
}

}

这样我就可以调用序列化我的二进制文件并将它们插入到 protobuf 的文本序列化中,然后再调用 protoc --encode :

IMAGE=$(mktemp)
OUTPUT=$(mktemp)
BIN_INSTANCE=$(mktemp)

echo -n 'capture: ' > $IMAGE
java -cp "$HOME/.m2/repository/com/google/protobuf/protobuf-java/3.0.0/protobuf-java-3.0.0.jar:target/protobuf-generator-1.0.0-SNAPSHOT.jar" protobuf.BinarySerializer image.jpg >> $IMAGE
sed -e 's/{UUID}/'$(uuidgen)'/' template.protobuf > $OUTPUT
sed -i '/{IMAGE}/ {
    r '$IMAGE'
    d
    }' $OUTPUT
cat $OUTPUT | protoc --encode=prototypesEvent.proto> $BIN_INSTANCE

template.protobuf 是:

uuid: "{UUID}"
image {
    capture: "{IMAGE}"
}
shell protocol-buffers
1个回答
2
投票

我认为它与java生成的相同。

基本上:

  • 空格 (0x20) 和波形符 (0x7e) 之间将其视为 ASCII 字符
  • 是否有捷径(例如 , , \ 等)使用快捷方式
  • 否则转义字符(八进制)

所以上面�是1个字节:八进制377或十进制255。

"\377\330\377\340 = 255 216 255 224

您应该能够将字符串复制到 Java/C 程序中并将其转换为字节

Java 代码看起来是:

  static String escapeBytes(final ByteSequence input) {
    final StringBuilder builder = new StringBuilder(input.size());
    for (int i = 0; i < input.size(); i++) {
      final byte b = input.byteAt(i);
      switch (b) {
        // Java does not recognize \a or \v, apparently.
        case 0x07: builder.append("\\a"); break;
        case '\b': builder.append("\\b"); break;
        case '\f': builder.append("\\f"); break;
        case '\n': builder.append("\\n"); break;
        case '\r': builder.append("\\r"); break;
        case '\t': builder.append("\\t"); break;
        case 0x0b: builder.append("\\v"); break;
        case '\\': builder.append("\\\\"); break;
        case '\'': builder.append("\\\'"); break;
        case '"' : builder.append("\\\""); break;
        default:
          // Only ASCII characters between 0x20 (space) and 0x7e (tilde) are
          // printable.  Other byte values must be escaped.
          if (b >= 0x20 && b <= 0x7e) {
            builder.append((char) b);
          } else {
            builder.append('\\');
            builder.append((char) ('0' + ((b >>> 6) & 3)));
            builder.append((char) ('0' + ((b >>> 3) & 7)));
            builder.append((char) ('0' + (b & 7)));
          }
          break;
      }
    }
    return builder.toString();
  }

取自 com.google.protobuf.TextFormatEscaper

© www.soinside.com 2019 - 2024. All rights reserved.