55

Is it possible to convert a string to a byte array and then convert it back to the original string in Java or Android?

My objective is to send some strings to a microcontroller (Arduino) and store it into EEPROM (which is the only 1  KB). I tried to use an MD5 hash, but it seems it's only one-way encryption. What can I do to deal with this issue?

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • Try using SHA128 if you're sending the string to an adruino. It's reversible; but I don't know if you'd need that code on the arduino. – Richard Barker Jul 06 '15 at 14:38

5 Answers5

127

I would suggest using the members of string, but with an explicit encoding:

byte[] bytes = text.getBytes("UTF-8");
String text = new String(bytes, "UTF-8");

By using an explicit encoding (and one which supports all of Unicode) you avoid the problems of just calling text.getBytes() etc:

  • You're explicitly using a specific encoding, so you know which encoding to use later, rather than relying on the platform default.
  • You know it will support all of Unicode (as opposed to, say, ISO-Latin-1).

EDIT: Even though UTF-8 is the default encoding on Android, I'd definitely be explicit about this. For example, this question only says "in Java or Android" - so it's entirely possible that the code will end up being used on other platforms.

Basically given that the normal Java platform can have different default encodings, I think it's best to be absolutely explicit. I've seen way too many people using the default encoding and losing data to take that risk.

EDIT: In my haste I forgot to mention that you don't have to use the encoding's name - you can use a Charset instead. Using Guava I'd really use:

byte[] bytes = text.getBytes(Charsets.UTF_8);
String text = new String(bytes, Charsets.UTF_8);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Isn't UTF-8 android platform default anyway? – ewanm89 Oct 30 '11 at 21:23
  • 1
    public static Charset defaultCharset () Since: API Level 1 Returns the system's default charset. This is determined during VM startup, and will not change thereafter. On Android, the default charset is UTF-8. – ewanm89 Oct 30 '11 at 21:25
  • 1
    @ewanm89: Well, the question says "in Java or Android" - I would personally be explicit about it anyway, just because on other Java platforms it's *not* always the default. It would be way too easy to share the code with (say) a servlet and then get the wrong results. – Jon Skeet Oct 30 '11 at 21:33
  • 1
    If you are on Android you can use StandardCharsets.UTF_8 – Ayyappa Feb 16 '16 at 11:38
16

You can do it like this.

String to byte array

String stringToConvert = "This String is 76 characters long and will be converted to an array of bytes";
byte[] theByteArray = stringToConvert.getBytes();

http://www.javadb.com/convert-string-to-byte-array

Byte array to String

byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46};
String value = new String(byteArray);

http://www.javadb.com/convert-byte-array-to-string

Michell Bak
  • 13,182
  • 11
  • 64
  • 121
  • 3
    I definitely *wouldn't* use that code. It assumes the platform default encoding is the same when used in both places, and also that the platform default encoding handles all the characters in the string. – Jon Skeet Oct 30 '11 at 21:23
  • Android's default charset is UTF-8, which is the same as you're suggesting, so there's really no reason not to do that. If you're going to use another kind of encoding, you should probably use the code in your suggestion and adjust it a bit to fit whatever charset you're using. – Michell Bak Oct 30 '11 at 21:29
  • I would still be explicit about it anyway. See the comment I've just left on my own answer, which I'll also edit *into* the answer. – Jon Skeet Oct 30 '11 at 21:34
  • I agree with your comment on Java in general, but it doesn't make any sense in Android. Why write some explicitly when it's already set by default? Doesn't make any sense. – Michell Bak Oct 30 '11 at 21:36
  • 1
    Because it's *only* the default in Android, and it would be all too easy for the code to be copied into a servlet without awareness that it was introducing a bug. Can you not see that happening? I'd *at least* write a comment stating that this is guaranteed to use UTF-8 on Android, and that it isn't guaranteed on other platforms. That comment would be significantly longer than explicitly specifying the encoding... – Jon Skeet Oct 30 '11 at 21:47
3

Use [String.getBytes()][1] to convert to bytes and use [String(byte[] data)][2] constructor to convert back to string.

Szere Dyeri
  • 14,916
  • 11
  • 39
  • 42
  • 3
    ... but don't use either of those without specifying an encoding, otherwise you're using the platform default encoding which may not even support all the characters in your string. – Jon Skeet Oct 30 '11 at 21:20
0
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;

public class FileHashStream 
{
    // write a new method that will provide a new Byte array, and where this generally reads from an input stream
    
    public static byte[] read(InputStream is) throws Exception
    {
        String path = /* type in the absolute path for the 'commons-codec-1.10-bin.zip' */;

        // must need a Byte buffer

        byte[] buf = new byte[1024 * 16]

        // we will use 16 kilobytes

        int len = 0;

        // we need a new input stream

        FileInputStream is = new FileInputStream(path);

        // use the buffer to update our "MessageDigest" instance

        while(true)
        {
            len = is.read(buf);
            if(len < 0) break;
            md.update(buf, 0, len);
        }

        // close the input stream

        is.close();

        // call the "digest" method for obtaining the final hash-result

        byte[] ret = md.digest();

        System.out.println("Length of Hash: " + ret.length);

        for(byte b : ret)
        {
            System.out.println(b + ", ");
        }

        String compare = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";

        String verification = Hex.encodeHexString(ret);

        System.out.println();

        System.out.println("===")

        System.out.println(verification);

        System.out.println("Equals? " + verification.equals(compare));
            
    }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
0

byte[] pdfBytes = Base64.decode(myPdfBase64String, Base64.DEFAULT)

Marco
  • 1
  • 1
  • 4
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 18 '22 at 10:46