Doorgaan naar hoofdcontent

Java String toBytes and from Bytes

Last week I was trying to encode some encrypted data as a cookie. After encrypting the data, I was left with a byte[] array. So all that was left was to create a string, and then fix all the strange characters... preferably by base64 encoding it, for example.
That worked fine, until I wanted to decode the string. All of a sudden the byte[] array was no longer the same... well, sometimes, it wasn't.

  byte[] data = new byte[20];
  new Random().nextBytes[data]; // fill with some random data.
  String myString = new String(data);
  byte[] fromString = myString.getBytes();
  for(int i = 0; i < data.length; i++) 
    assert(data[i] == fromString[i])
The code above will fail... from time to time. This is rather strange, and not directly obvious from the javadoc. First I considered if it was an encoding problem. This only compounded the issue, as
  new String(data, "UTF-16" ).getBytes().length 
is twice the size of the original data. That was leading nowhere. After looking and testing I finally figured it out: Java String constructor with bytes assumed those bytes are from a string! If they are not, then the (logical) idempotence of new String().getBytes() does not hold!
What was actually necessary was encoding those bytes to a string... say a base64 string! Most base64 libraries support encoding bytes to a base64 byte[] array, and the apache commons codec also allows encoding to a string.
Better yet, they allow encoding to an url safe string, which does not contain +,= or /. And it has a proper decoding of such a string too. Presto!

Reacties

Populaire posts van deze blog

Spring's conditional annotation with properties

Spring has a nice @Conditional annotation, to have the option to have beans be available in the context depending a specific condition (Of course, this can also be realized by using @Configuration objects, but that's a different post). Ideally, we'd have the option to have a condition evaluate to true or false depending on a property. Sadly, Spring does not support that out of the box. Googling and looking around gives a partial solution, but the complete one here, so we won't forget: /** * Components annotated with ConditionalOnProperty will be registered in the spring context depending on the value of a * property defined in the propertiesBeanName properties Bean. */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Conditional(OnPropertyCondition.class) public @interface ConditionalOnProperty { /** * The name of the property. If not found, it will evaluate to false. */ String value(); /** * if the p...

OSGI insights without sonar

So I was on a project without sonar. Oh my. Well, it was an OSGI project, so the problems couldn't be that bad, right? But how good were they (and what things were bad?) I found Stan4j , a code analysis tool for eclipse, which draws nice graphs and can handle osgi pretty well it seems. Now I can see that dependencies/bundle names aren't properly aligned (even though OSGI doesn't complain), etc.

JPA and transactions

So I was working with JPA and transactions. Consider the following: In bean 1, with implicit TX 1, managed entities are loaded/created,and returned in bean 2, with implicit TX 2, entities are modified in bean 3, with NO TX, bean 1 is called, and the results are passed to bean 2. and bean 4 is similar to bean 3, but with it's own transaction, TX3 What happens when bean 3 finishes: are the entities updated? What happens when bean 4 finishes, are the entities updated? The answer to this is simple; entities are managed through a persistance context. That context is tied to the transaction. So in bean 2, there is a difference. When called from bean 3, it runs in a different transaction then bean 1, and thus a different persistance context, and thus the entities are not managed 'by this transaction'.When called from bean 4, it all runs in the same transaction, TX3, and the results are persisted.