Stack Exchange
Base64 encoding of Crc32c (long) value
Working on a google cloud storage projectm, I am trying to caclculate the Crc32c value and get the base64 encoding of the long value return by crc32c algorithm. To calculate crc32c I'm using
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 is the encoded string returned by google cloud storage
 assertEquals(GCSReturnedCrc, mEncodedCrc);   

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

Other related links: https://developers.google.com/storage/docs/hashes-etags#_JSONAPI

Your expected hash is too long; CRC32C is defined as exactly 4 bytes, but the Google Crc32c implementation returns a long.  It does this to have compatibility with java.util.zip.Checksum and to avoid signedness issues with putting a 4-byte quantity in a signed int.  Instead you must remove the first four leading bytes via:
Arrays.copyOfRange(Longs.toByteArray(crcValue), 4, 8);
I also opened a pull request against crc32c-java which may help avoid this problem in the future:
https://github.com/GoogleCloudPlatform/crc32c-java/pull/2

I'm a bit confused. You're base64 encoding the string form of the CRC32C hash's long value. Is that really correct? It just seems unlikely to me, as the main reason for base64 encoding something is because it's not in a readable form such as a String. It seems more likely that you should be base64 encoding the 4 bytes of the CRC32C hash itself (it's a 32-bit hash function).
You can get that like this:
...
byte[] crcBytes = Ints.toByteArray((int) crc32c.getValue());
// byte[] crcBytes = crc32c.getValueAsBytes(); (method that was just added)
String base64 = BaseEncoding.base64().encode(crcBytes);

FYI, we're releasing Hashing.crc32c() in Guava 18, which should make this even easier.
byte[] crc32c = byteSource.hash(Hashing.crc32c()).asBytes();
String base64 = BaseEncoding.base64().encode(crc32c);


Thanks for adding Hashing.crc32c!  This avoids the original issue entirely.

You could try a bit harder yourself: When the encoded values don't match, why not decode them back and look at them:
Long.parseLong(new String(BaseEncoding.base64().decode("MjY0MDc0ODQwNQ==")))

returns 2640748405. This looks fine.
BaseEncoding.base64().decode("nWafdQ==")

returns the bytes in hexadecimal 9D,66,9F,75, and converting them back into a String depends on the Charset used. With UTF-8 you get �f�u. With no charset you get a String representing a number.
OTOH your snippet looks fine... so start a debugger or add some debugging output.
Btw., I'd suggest to avoid locale-dependent methods like String#getBytes.

Yeah Sting.getBytes is not a good option here.I replaced it with Longs.toByteArray(value). But still not getting it right.Anyway
thank you very much for the support.

@BhathiyaSupun Note that both methods produce a byte[], but in a completely different way. I'd go for String#getBytes(charset), which is platform-independent. Did you output crcValue?
