Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting char[] to byte[]

I would like to convert a character array to a byte array in Java. What methods exists for making this conversion?

like image 346
Arun Abraham Avatar asked Apr 01 '11 12:04

Arun Abraham


People also ask

How do I convert a char to a byte?

Syntax: byte by = (byte) ch; Here, ch is the char variable to be converted into Byte. It tells the compiler to convert the char into its byte equivalent value.

Can you print [] byte?

You can simply iterate the byte array and print the byte using System. out. println() method.

How do you convert bytes to character in Java?

To get the right point use char c = (char) (b & 0xFF) which first converts the byte value of b to the positive integer 200 by using a mask, zeroing the top 24 bits after conversion: 0xFFFFFFC8 becomes 0x000000C8 or the positive number 200 in decimals.


1 Answers

Convert without creating String object:

import java.nio.CharBuffer; import java.nio.ByteBuffer; import java.util.Arrays;  byte[] toBytes(char[] chars) {   CharBuffer charBuffer = CharBuffer.wrap(chars);   ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);   byte[] bytes = Arrays.copyOfRange(byteBuffer.array(),             byteBuffer.position(), byteBuffer.limit());   Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data   return bytes; } 

Usage:

char[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; byte[] bytes = toBytes(chars); /* do something with chars/bytes */ Arrays.fill(chars, '\u0000'); // clear sensitive data Arrays.fill(bytes, (byte) 0); // clear sensitive data 

Solution is inspired from Swing recommendation to store passwords in char[]. (See Why is char[] preferred over String for passwords?)

Remember not to write sensitive data to logs and ensure that JVM won't hold any references to it.


The code above is correct but not effective. If you don't need performance but want security you can use it. If security also not a goal then do simply String.getBytes. Code above is not effective if you look down of implementation of encode in JDK. Besides you need to copy arrays and create buffers. Another way to convert is inline all code behind encode (example for UTF-8):

val xs: Array[Char] = "A ß € 嗨 𝄞 🙂".toArray val len = xs.length val ys: Array[Byte] = new Array(3 * len) // worst case var i = 0; var j = 0 // i for chars; j for bytes while (i < len) { // fill ys with bytes   val c = xs(i)   if (c < 0x80) {     ys(j) = c.toByte     i = i + 1     j = j + 1   } else if (c < 0x800) {     ys(j) = (0xc0 | (c >> 6)).toByte     ys(j + 1) = (0x80 | (c & 0x3f)).toByte     i = i + 1     j = j + 2   } else if (Character.isHighSurrogate(c)) {     if (len - i < 2) throw new Exception("overflow")     val d = xs(i + 1)     val uc: Int =        if (Character.isLowSurrogate(d)) {         Character.toCodePoint(c, d)       } else {         throw new Exception("malformed")       }     ys(j) = (0xf0 | ((uc >> 18))).toByte     ys(j + 1) = (0x80 | ((uc >> 12) & 0x3f)).toByte     ys(j + 2) = (0x80 | ((uc >>  6) & 0x3f)).toByte     ys(j + 3) = (0x80 | (uc & 0x3f)).toByte     i = i + 2 // 2 chars     j = j + 4   } else if (Character.isLowSurrogate(c)) {     throw new Exception("malformed")   } else {     ys(j) = (0xe0 | (c >> 12)).toByte     ys(j + 1) = (0x80 | ((c >> 6) & 0x3f)).toByte     ys(j + 2) = (0x80 | (c & 0x3f)).toByte     i = i + 1     j = j + 3   } } // check println(new String(ys, 0, j, "UTF-8")) 

Excuse me for using Scala language. If you have problems with converting this code to Java I can rewrite it. What about performance always check on real data (with JMH for example). This code looks very similar to what you can see in JDK[2] and Protobuf[3].

like image 106
tellnobody1 Avatar answered Oct 07 '22 03:10

tellnobody1