Base64编码的Crc32c(long)值

时间:2014-08-02 15:45:33

标签: java base64 guava google-cloud-storage crc32

在google云存储项目中工作,我正在尝试计算Crc32c值并通过crc32c算法获取long值返回的base64编码。使用

计算crc32c I' m

https://github.com/GoogleCloudPlatform/crc32c-java/blob/master/src/com/google/cloud/Crc32c.java

  Crc32c crc32c = new Crc32c();
  crc32c.update(byteSource.read(), 0, byteArrayLength);
  long crcValue = crc32c.getValue();
  byte[] bArray = String.valueOf(crcValue).getBytes();
  String mEncodedCrc = BaseEncoding.base64().encode(bArray);

// GCSReturnedCrc是谷歌云存储返回的编码字符串

 assertEquals(GCSReturnedCrc, mEncodedCrc);   

//结果

 java.lang.AssertionError: expected [MjY0MDc0ODQwNQ==] but found [nWafdQ==]` 

其他相关链接:https://developers.google.com/storage/docs/hashes-etags#_JSONAPI

3 个答案:

答案 0 :(得分:3)

您预期的哈希值太长; CRC32C定义为4个字节,但Google Crc32c实现返回一个长整数。这样做是为了与java.util.zip.Checksum兼容,并避免在将4字节数量放入signed int中时出现签名问题。相反,您必须通过以下方法删除前四个前导字节:

Arrays.copyOfRange(Longs.toByteArray(crcValue), 4, 8);

我还打开了针对crc32c-java的pull请求,这有助于避免将来出现此问题:

https://github.com/GoogleCloudPlatform/crc32c-java/pull/2

答案 1 :(得分:1)

我有点困惑。您对base32编码CRC32C哈希值long字符串形式进行了base64。这是真的正确吗?对我来说这似乎不太可能,因为base64编码的主要原因是因为它的不是以可读的形式,例如String。您似乎更有可能对CRC32C哈希本身的4个字节进行base64编码(它是一个32位哈希函数)。

你可以这样:

...
byte[] crcBytes = Ints.toByteArray((int) crc32c.getValue());
// byte[] crcBytes = crc32c.getValueAsBytes(); (method that was just added)
String base64 = BaseEncoding.base64().encode(crcBytes);

仅供参考,我们在Guava 18中releasing Hashing.crc32c(),这应该会让这更容易。

byte[] crc32c = byteSource.hash(Hashing.crc32c()).asBytes();
String base64 = BaseEncoding.base64().encode(crc32c);

答案 2 :(得分:0)

你可以自己尝试一下:当编码值不匹配时,为什么不对它们进行解码并查看它们:

Long.parseLong(new String(BaseEncoding.base64().decode("MjY0MDc0ODQwNQ==")))

返回2640748405。这看起来很好。

BaseEncoding.base64().decode("nWafdQ==")

以十六进制9D,66,9F,75返回字节,并将它们转换回字符串取决于所使用的字符集。使用UTF-8,您将获得�f�u。如果没有字符集,则会得到一个代表数字的String

OTOH您的代码段看起来很好......所以启动调试器或添加一些调试输出。

顺便说一下,我建议避免像String#getBytes这样的依赖于语言环境的方法。