2016-11-28 2 views
0

Я смотрю на выходе команды protoc --decode, и я не могу понять кодировку, когда он встречает байт:Что такое кодировка двоичного кода, используемая protoc -decode?

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

код [...] был добавлен мной, чтобы сократить выход.

Что такое кодирование?

Редактировать

Так на основе ответа Брюса я написал свою собственную утилиту для того, чтобы генерировать выборки данных из сценария оболочки:

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}" 
} 
+0

Вопрос о бонусе: что такое ** цель ** этого формата? Стандарт де-факто для отображения двоичных файлов - это печать их шестнадцатеричных значений. Почему кто-то подумал, что было хорошей идеей отображать восьмеричные значения? И еще больше раздражает, почему они заменяют некоторые байтовые значения соответствующими символами ASCII в этом странном формате вывода? – Alderath

ответ

1

Я предполагаю это Samer как произведено Java.

в основном: * между пространством (0x20) и тильдой (0x7E) рассматривать его как ASCII символ * если есть ярлык (например, \ п, \ г, \ и т.д.) с помощью ярлыка * в противном случае, спасаясь от символ (восьмеричный)

поэтому в приведенных выше \ 377 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

+0

Хорошо, спасибо за ответ. Я надеялся, что смогу найти утилиту * nix, чтобы сгенерировать ее для меня, но, наверное, мне придется что-то взломать. – user691154

+0

В протоколах-буферах будет использоваться метод Code/Decode для формата на большинстве языков, имя класса, вероятно, будет похоже на Java –