android.util.Base64 encoded String too short - java

I am using android.util.Base64 and want to encode a bitmap to a base64-string, but it is always too short. For instance an online tool says, it has an invalid length and compared to an valid one it is surely too short.
This is my code:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
String encodedImage = Base64.encodeToString(b, Base64.DEFAULT);
Here is an example of the different length of the strings:
My string
valid string

Your code looks fine but you can verify it by using this code:
byte[] b2 = Base64.decode(encodedImage, Base64.DEFAULT);
boolean equals = Arrays.equals(b, b2);
If the two arrays have equal contents then the problem is not on the Base64 but in the way that you're using the encodedImage string. Remember that things like LogCat might truncate strings that exceed a certain length, so make sure that you print out the length of the encodedImage string and compare it to the Base64 you've got.
Also, Base64 encoded strings are 4/3 (133%) longer than the original, so if the ByteArrayOutputStream has length 9000, your base64 string is expected to have length 12000.

Related

Base64 decoding a normal unencoded string in android not give any exception

Decoding with base64 an unencoded string on Android does not gives any error but returns a string with some special characters e.g encoded like.
It should throw some IllegalArgumentException. Is there some native way in android to check that other than regex ?
private String decodeThisString = "I am a java String";
bytes[] deocdedBytes = Base64.decode(decodeThisString.getBytes(), Base64.DEFAULT);
I think you do not need to remove the character when you will decode it, automatically they will be discarded at the time of decode. I have tested with encoding and decoding with the provided code and get the exact string after decode.
String decodeThisString = "I am a java String";
//encode
byte[] data = Base64.encode(decodeThisString.getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
String text = new String(data, StandardCharsets.UTF_8);
//decode
byte[] datas = Base64.decode(text, Base64.DEFAULT);
String texts = new String(datas, StandardCharsets.UTF_8);

How to convert byte[] to String in Java?

There are some SO quetions but no helped me. I would like to convert byte[] from org.apache.commons.codec.digest.HmacUtils to String. This code produces some weird output:
final String value = "value";
final String key = "key";
byte[] bytes = HmacUtils.hmacSha1(key, value);
String s = new String(bytes);
What am I doing wrong?
Try to use:
String st = HmacUtils.hmacSha1Hex(key, value);
First, the result of hmacSha1 would produce a digest, not not a clear String. Besides, you may have to specify an encoding format, for example
String s = new String(bytes, "US-ASCII");
or
String s = new String(bytes, "UTF-8");
For a more general solution, if you don't have HmacUtils available:
// Prepare a buffer for the string
StringBuilder builder = new StringBuilder(bytes.length*2);
// Iterate through all bytes in the array
for(byte b : bytes) {
// Convert them into a hex string
builder.append(String.format("%02x",b));
// builder.append(String.format("%02x",b).toUpperCase()); // for upper case characters
}
// Done
String s = builder.toString();
To explain your problem:
You are using a hash function. So a hash is usually an array of bytes which should look quite random.
If you use new String(bytes) you try to create a string from these bytes. But Java will try to convert the bytes to characters.
For example: The byte 65 (hex 0x41) becomes the letter 'A'. 66 (hex 0x42) the letter 'B' and so on. Some numbers can't be converted into readable characters. Thats why you see strange characters like '�'.
So new String(new byte[]{0x41, 0x42, 0x43}) will become 'ABC'.
You want something else: You want each byte converted into a 2 digit hex String (and append these strings).
Greetings!
You may need to have an encoding format. Check out this link here.
UTF-8 byte[] to String

byte[] to string and String to byte[] keeping information unchanged

I have the byte array of a string.
How to convert byte[] to String and String to byte[]
After compressing I get the compressed value in form of byte array.
byte[] value at System.out is
h?ö\
É·ë’YO¸p˜à¼Œ[䔽"$žQºÍCïηfØzöÛBi¤!<
How can I convert this byte array value to String keeping its value unchanged and then getting it back to byte array for decompressing?
tried buitin functions but they change the whole compressed byte array
try new String(byteArray)
and string.getBytes()
Use ISO-8859-1 when converting bytes to String and back
String s = new String(bytes, "ISO-8859-1");
bytes = s.getBytes("ISO-8859-1");
You need to specify the char set for your byte[] array while decoding from raw into string.
The String type contain such constructor String(bytes, Charset charset)
byte[] b=new byte[10];
b[0]=100;
b[1]=101;
b[2]=102;
b[5]=0;
b[6]=0;
String st=new String(b);
System.out.println(st);//def
b=st.getBytes();
for(int i=0;i<b.length;i++){
System.out.println(b[i]);
}

byte to string and vice versa

I need to convert a salt value randomly generated and store it in the database. To store it in the database I converted it to a string. Then for retrieving the original value, I convert it back to byte. But both value are not matching. I have tried "UTF-8","UTF-16", BASE64Encoder.
SecureRandom ranGen = new SecureRandom();
byte[] aesKey = new byte[16]; // 16 bytes = 128 bits
ranGen.nextBytes(aesKey);
System.out.println(aesKey);
String a=new String(aesKey,"UTF-16");
byte[] b=new byte[16];
b=a.getBytes("UTF-16");
System.out.println(b);
Outputs for the above code(Executed it 2 times):
[B#11563ff
[B#1581593
and
[B#170888e
[B#11563ff
You really ought to use Base64 for converting binary data to Strings. There are lots of free implementations available, for example the one found in Apache Commons Codec.
Also, it's really easy to use, for example:
For encoding:
import org.apache.commons.codec.binary.Base64;
...
byte[] abValue = {...}; // Your data to encode
Base64 base64 = new Base64();
String strEncodedData = base64.encodeToString(abValue).trim();
For decoding:
import org.apache.commons.codec.binary.Base64;
...
String strEncodedData = "..."; // Your previously encoded data
Base64 base64 = new Base64();
byte[] abValue = base64.decode(strValue);
As your code is written above, printing aesKey and then b, what you are actually printing is the output of the toString method for an array object, which is just the default Object toString method. So I don't see how you can expect them to be the same.
If you really want to check they are the same you should compare them byte by byte.
In terms of your actual question regarding storing a byte[] as a String in the DB, your best bet is to Base64 encode it. I would suggest using the Apache Commons Codec library for this. See the user guide.
EDIT:
Using the BASE64Encode and BASE64Decoder you have referred to, the code would be like this:
SecureRandom ranGen = new SecureRandom();
byte[] aesKey = new byte[16]; // 16 bytes = 128 bits
ranGen.nextBytes(aesKey);
String a = new BASE64Encoder().encode(aesKey);
System.out.println(a);
byte[] b = new BASE64Decoder().decodeBuffer(a);
System.out.println(new BASE64Encoder().encode(b));
for (int i = 0; i < aesKey.length; i++) {
System.out.println(aesKey[i] + " " + b[i]);
}
Here, I have also looped through the bytes individually, to show that they are indeed equal.

How do I convert a byte array to Base64 in Java?

Okay, I know how to do it in C#.
It's as simple as:
Convert.ToBase64String(byte[])
and Convert.FromBase64String(string) to get byte[] back.
How can I do this in Java?
Java 8+
Encode or decode byte arrays:
byte[] encoded = Base64.getEncoder().encode("Hello".getBytes());
println(new String(encoded)); // Outputs "SGVsbG8="
byte[] decoded = Base64.getDecoder().decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64.getEncoder().encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(Base64.getDecoder().decode(encoded.getBytes()));
println(decoded) // Outputs "Hello"
For more info, see Base64.
Java < 8
Base64 is not bundled with Java versions less than 8. I recommend using Apache Commons Codec.
For direct byte arrays:
Base64 codec = new Base64();
byte[] encoded = codec.encode("Hello".getBytes());
println(new String(encoded)); // Outputs "SGVsbG8="
byte[] decoded = codec.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
Base64 codec = new Base64();
String encoded = codec.encodeBase64String("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(codec.decodeBase64(encoded));
println(decoded) // Outputs "Hello"
Spring
If you're working in a Spring project already, you may find their org.springframework.util.Base64Utils class more ergonomic:
For direct byte arrays:
byte[] encoded = Base64Utils.encode("Hello".getBytes());
println(new String(encoded)) // Outputs "SGVsbG8="
byte[] decoded = Base64Utils.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64Utils.encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = Base64Utils.decodeFromString(encoded);
println(new String(decoded)) // Outputs "Hello"
Android (with Java < 8)
If you are using the Android SDK before Java 8 then your best option is to use the bundled android.util.Base64.
For direct byte arrays:
byte[] encoded = Base64.encode("Hello".getBytes());
println(new String(encoded)) // Outputs "SGVsbG8="
byte [] decoded = Base64.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64.encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(Base64.decode(encoded));
println(decoded) // Outputs "Hello"
Use:
byte[] data = Base64.encode(base64str);
Encoding converts to Base64
You would need to reference commons codec from your project in order for that code to work.
For java8:
import java.util.Base64
Additionally, for our Android friends (API Level 8):
import android.util.Base64
...
Base64.encodeToString(bytes, Base64.DEFAULT);
In case you happen to be using Spring framework along with java, there is an easy way around.
Import the following.
import org.springframework.util.Base64Utils;
Convert like this.
byte[] bytearr ={0,1,2,3,4};
String encodedText = Base64Utils.encodeToString(bytearr);
To decode you can use the decodeToString method of the Base64Utils class.

Categories

Resources