• Post Reply Bookmark Topic Watch Topic
  • New Topic

How to encode a long into base64 and get it back?  RSS feed

 
Alan Blass
Ranch Hand
Posts: 166
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi!

I want to encode a long into base64 and decode it back. I have:



But I am not getting it to be the same value. Can someone help?

Thanks.
 
Tim Moores
Saloon Keeper
Posts: 4032
94
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What are you getting? What's the for loop supposed to do? Have you tried "new String(epochtime1)" instead?
 
Rob Spoor
Sheriff
Posts: 21135
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tim probably means new String(receivedEpoch) in combination with parseLong, and I think he's right.
There are at least two ways of converting a long into a byte[] and vice versa, and you've mixed the two. Instead you should match the long to byte[] conversion and the byte[] to long conversion. With the new String fix you'll do that. Alternatively, and this would be my preferred way, is to change the long into a byte[] in a similar way as your original byte[] to long conversion. Right now, your byte[] will contain about 13 elements, whereas you only need 8 (64 bits / 8 bits).
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alan Blass wrote:I want to encode a long into base64 and decode it back. I have:
...
But I am not getting it to be the same value. Can someone help?

The others are right, the problem is in your
byte [] epochtime1 = Base64.encodeBase64(String.valueOf(t).getBytes());
line.

Base64 is a binary, not a String, encoding. Therefore, as Rob said, you need to convert your long to an array of bytes containing it's binary representation.
One possibility is to use BigInteger, viz:
byte [] epochtime1 = Base64.encodeBase64( BigInteger.valueOf(t).toByteArray() );
but you may run into problems with that method if you use it on more than 1 value, because it does NOT pad the returned array to the correct length. I leave that for you as an exercise.

HIH

Winston
 
Alan Blass
Ranch Hand
Posts: 166
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi!

Thanks for your replies.

Strange thing is when I print out the encoded base 64 from 1328175927236, I get [B@7b582c6f. But if I use an online base64 encoder to encode 1328175927236, I get: MTMyODE3NTkyNzIzNg==

Below is my code:



In addition, what if the received epochtime is a String? Should I use:

byte[] receivedEpoch = Base64.decodeBase64(epochtime1.getBytes());


Please help. Thanks
 
Rob Spoor
Sheriff
Posts: 21135
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alan Blass wrote:Strange thing is when I print out the encoded base 64 from 1328175927236, I get [B@7b582c6f.

That's because arrays don't override toString() and therefore use the implementation provided by java.lang.Object: the class name ([B for byte arrays) followed by @ and the hexadecimal hash code. Use Arrays.toString(epochtime1) instead.
 
Alan Blass
Ranch Hand
Posts: 166
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi!

I get this:

received base64: [65, 84, 85, 57, 100, 69, 47, 69].

I have also looked up the ASCII table 65 is A in decimal. It is suppose to be M. How do I get the encoded Base64?
My code:



What should I use if the encoded epochtime is a string instead of byte array?

Thanks.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Alan Blass wrote:I have also looked up the ASCII table 65 is A in decimal. It is suppose to be M. How do I get the encoded Base64?

Well, first, as I said, look at the number of bytes you're getting back from BigInteger.toByteArray(). If it isn't 8 (although it looks like it should be), you may well end up with a different base64 result.

Second, "MTMyODE3NTkyNzIzNg==" looks like the result of a complete file to me, which I wouldn't expect from a Java method (there may be more values to append); so you need to find out what it's padding philosophy is (the two '=' at the end are padding, but I can't remember the exact algorithm). Also, when encoding a complete value, the number of bytes is often put at the front. Certainly, what you're seeing is way more than just a long.

There is a lot to know about base64, and I suspect you need to do some reading, rather than just "expecting" your encoded value to be the same as what you see from an outside source.

Another suggestion: go through the exercise yourself, and work out what you would expect from your long value. It's tedious, but at least you'll be a bit further on.

What should I use if the encoded epochtime is a string instead of byte array?

If it is, you're in big trouble, and whoever provided you with the data should have nasty things done to their reproductive organs.

Winston

PS: Just one other thing. You may also need to check the "endian" that the class uses. BigInteger.toByteArray() returns its bytes in big-endian "digit" order, which goes along with Java's philosophy of all binary numbers being 'big-endian'. If that's not what the method is expecting you could get garbage.

As I said above - lots of reading.
 
Rob Spoor
Sheriff
Posts: 21135
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"MTMyODE3NTkyNzIzNg==" decodes to [49, 51, 50, 56, 49, 55, 53, 57, 50, 55, 50, 51, 54] which is in String form "1328175927236". That looks like a time stamp to me.
[65, 84, 85, 57, 100, 69, 47, 69] is the byte representation of String "ATU9dE/E". If I instead convert that byte[] into a long I either get 4707481215492763461 or 4985279609283368001, depending on the endianness.

Now I think I haven't got my message through last time. If you convert the long into a String, then turn the String into a byte[] for encoding, you must convert the decoded byte[] back into a String which you then parse into a long. If you want to convert the decoded byte[] using your long calculation, then you must create the byte[] for encoding using a similar long calculation. In other words, the method for converting a long into a byte[] must be the inverse of converting a byte[] into a long.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Spoor wrote:"MTMyODE3NTkyNzIzNg==" decodes to [49, 51, 50, 56, 49, 55, 53, 57, 50, 55, 50, 51, 54] which is in String form "1328175927236". That looks like a time stamp to me.

Well spotted that man.

My question: Why would anyone encode a string in base64, which
(a) is designed for encoding binary data.
(b) produces a string that is longer than the original one (well, longer than an ASCII string anyway ).
???

Winston

 
Alan Blass
Ranch Hand
Posts: 166
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok. I got it. Thanks everyone.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!