1

I am probably overlooking something silly, but I've never had to deal with binary in code and thought it'd be a good idea to practice it in an encryption program, for kicks. Long story short, I'm able to convert a string into binary (in the form of a string), but can't figure out how to do the reverse.

Right now, I have something like this:

public static String bytesToString(String bytes){
    int i = bytes.length()/8;
    int pos = 0;
    String result = "";
    for(int j=0; j<i; j++){
        String temp = bytes.substring(pos,pos+8);
        byte b = (byte) Integer.parseInt(temp);
        result = result + Byte.toString(b);
        pos++;
    }
    System.out.println("Result: " + result);
    return result;
}

I think the bytes are being parsed as literal numbers. What am I missing? Edit: To clarify, I will previously have parsed a string of text into bits and written them to a string. I want to split this string into bytes and parse them back into letters. It would take "011010000110010101111001" and return "hey".

Salem
  • 1,122
  • 4
  • 19
  • 30
  • Can you please post an example of what are you trying to achieve? – Op De Cirkel Jun 03 '11 at 03:03
  • I **strongly** recommend storing unencrypted strings as `java.lang.String`s, and "binary" strings (e.g. the string's binary representation) as `byte[]`. Storing the 3 bytes `01101000 01100101 01111001` in a string as `"011010000110010101111001"` instead of `"hey"` takes up **sixteen times** as much space (since Java represents strings internally as UTF-16, meaning that every character is stored as 2 bytes). What's even worse is that the **meaning** of the code is clouded (_Is this string a "real" string or a "byte" string?_) and **performance will suffer.** – Matt Ball Jun 03 '11 at 03:41

4 Answers4

5

How about using Integer.parseInt(text, 2)? As in,

public static int binaryToInt(String binary)
{
    return Integer.parseInt(binary, 2);
}

I'm not sure why your binaryToString method both takes and returns a string.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • Because I want to return letters. For example, "hi," in binary, is 0110100001101001. I'd give this method 0110100001101001 with the hopes of it being split into 01101000 01101001 and then returned as "hi." – Salem Jun 03 '11 at 03:01
  • 1
    In that case I'd strongly recommend using [`String#getBytes("UTF-8")`](http://download.oracle.com/javase/6/docs/api/java/lang/String.html#getBytes(java.lang.String)) and [`new String(byteArray, "UTF-8")`](http://download.oracle.com/javase/6/docs/api/java/lang/String.html#String%28byte%5B%5D%2C%20java.lang.String%29) rather than trying to roll your own methods. Store strings as strings, and byte arrays as byte arrays. – Matt Ball Jun 03 '11 at 03:07
1

Integer.parseInt(temp) will attempt to read temp as a number and return the corresponding int. For example, Integer.parseInt("123") returns 123

EDIT: Be aware that the binary value of a character or text depends on the encoding you are using. For example "hi" is 0110100001101001 in ASCII but it may not in UTF-16 or UTF-32. And Java encodes characters into UTF-16 characters: see http://download.oracle.com/javase/6/docs/api/java/lang/String.html (for this reason Java chars are 16-bit unsigned integers).

So your bytesToString method must treat input differently depending on the encoding of the input. Or you may write it specifically for ASCII characters, and maybe rename it to, say, asciiBytesToString

You'd better see:

ignis
  • 8,692
  • 2
  • 23
  • 20
  • A string consisting solely of ASCII characters will be encoded identically by ASCII and UTF-8 since UTF-8 is a strict superset of ASCII. This, among other reasons, is a good reason to use UTF-8. – Matt Ball Jun 03 '11 at 03:11
  • yes but "A String represents a string in the UTF-16 format" (taken from the javadoc) – ignis Jun 03 '11 at 03:13
  • Doesn't matter. UTF-16 is the _internal_ string representation used by java. – Matt Ball Jun 03 '11 at 03:36
1
public class BinaryStringToChars {
  public static void main(String[] args) {
    String bin = "011010000110010101111001";

    StringBuilder b = new StringBuilder();
    int len = bin.length();
    int i = 0;
    while (i + 8 <= len) {
      char c = convert(bin.substring(i, i+8));
      i+=8;
      b.append(c);
    }
    System.out.println(b.toString());
  }

  private static char convert(String bs) {
    return (char)Integer.parseInt(bs, 2);
  }
}
Op De Cirkel
  • 28,647
  • 6
  • 40
  • 53
0

You need to advance 8 digits at a time, not digit by digit. Otherwise you are reusing bits. Also, you need to tell Integer.parseInt() what radix you want to use, since parseInt(String val) cannot really detect binary (you want Integer.parseInt(String val, int radix). You also need to choose a character encoding to convert bytes into characters (they are not the same thing!). Assuming ISO-8859-1 is ok:

public static String bytesToString(String bytes){
    int i = bytes.length()/8;
    int pos = 0;
    String result = "";
    byte[] buffer = new byte[i];
    for(int j=0; j<i; j++){
        String temp = bytes.substring(pos,pos+8);
        buffer[j] = (byte) Integer.parseInt(temp, 2);
        pos+=8;
    }
    result = new String(buffer, "ISO-8859-1");
    System.out.println("Result: " + result);
    return result;
}
Jerome
  • 1,429
  • 11
  • 13