Converting a binary string to an ASCII string, the longer way I had an interview recently and discovered that I'd forgotten some of the basics.  I've been playing around again and have written a function that will take a binary string (there is no validation yet) and returns the ASCII representation of said string.

I'm looking for advice or tips on how it could be improved. I don't want to use any of the API functions, this is more of a playground scenario in which I might be able to learn something.

public static String convertBinaryStringToString(String string){
    StringBuilder sb = new StringBuilder();
    char[] chars = string.replaceAll("\\s", "").toCharArray();
    int [] mapping = {1,2,4,8,16,32,64,128};

    for (int j = 0; j &lt; chars.length; j+=8) {
        int idx = 0;
        int sum = 0;
        for (int i = 7; i&gt;= 0; i--) {
            if (chars[i+j] == '1') {
                sum += mapping[idx];
            }
            idx++;
        }
        System.out.println(sum);//debug
        sb.append(Character.toChars(sum));
    }
    return sb.toString();
}


Sample output:


01101000 01100101 01101100 01101100 01101111 
104
101
108
108
111
hello
int [] mapping = {1,2,4,8,16,32,64,128};


This seems avoidable - array access could be replaced with a bitshift. It'd also clear up what you're doing...

for (int j = 0; j &lt; chars.length; j+=8) {
    int idx = 0;
    int sum = 0;
    for (int i = 7; i&gt;= 0; i--) {
        if (chars[i+j] == '1') {
            sum += 1 &lt;&lt; idx;
        }
        idx++;
    }
    System.out.println(sum);//debug
    sb.append(Character.toChars(sum));
}


It's only after making this change that I understand what you're doing! You're splitting the input string into segments that represent a single character (I got that far already), but after that, you start at the back of the represented character, and check for each bit representing character that it is '1'. If it's '1' (and thus not '0'), you add the value that the bit would represent to sum. Once you've gone through a single character representation, you let Character.toChars cast the int-value of the character back to a character. Then you add it to the result buffer, which will form the full string.

Phew.

You need more comments, so that other developers can read and understand directly how this method works.

Specifically, 1 comment to explain what your replaceAll does (regex are not obvious to me and I have to look them up), and 1 comment to say that you're parsing bits in reverse per character.

Maybe like so:

//for each character
for (int j = 0; j &lt; chars.length; j+=8) {
    int idx = 0;
    int sum = 0;
    //for each bit in reverse
    for (int i = 7; i&gt;= 0; i--) {
        if (chars[i+j] == '1') {
            sum += 1 &lt;&lt; idx;
        }
        idx++;
    }
    System.out.println(sum);//debug
    sb.append(Character.toChars(sum));
}




Getting rid of all the built-in functions (for fun only)

So you want to do everything yourself?

This is bad style, since everything in java.lang (and in generally, java.util as well) can be relied on without turning this into a puzzle for your fellow programmers, but I'll humor you.

First, you can get rid of the String.split via Thomas Junk's answer, incrementing by 9 each time instead.

public static String convertBinaryStringToString(String string){
    StringBuilder sb = new StringBuilder();
    char[] chars = string.toCharArray();

    //for each character
    for (int j = 0; j &lt; chars.length; j+=9) {
        int idx = 0;
        int sum = 0;
        //for each bit in reverse
        for (int i = 7; i&gt;= 0; i--) {
            if (chars[i+j] == '1') {
                sum += 1 &lt;&lt; idx;
            }
            idx++;
        }
        System.out.println(sum);//debug
        sb.append(Character.toChars(sum));
    }
    return sb.toString();
}


Leaves us with this bit of code.

We can get rid of the StringBuilder by writing to a char[]. We can get rid of Character.toChars(sum) with (char) sum. We do have to make a new string out of the character array, though.

public static String convertBinaryStringToString(String string){
    char[] chars = string.toCharArray();
    char[] transcoded = new char[(chars.length / 9)+1];

    //for each character (plus one for spacing)
    for (int j = 0; j &lt; chars.length; j+=9) {
        int idx = 0;
        int sum = 0;

        //for each bit in reverse
        for (int i = 7; i&gt;= 0; i--) {
            if (chars[i+j] == '1') {
                sum += 1 &lt;&lt; idx;
            }
            idx++;
        }
        transcoded[j/9] = (char) sum;
    }
    return new String(transcoded);
}


And voila, we're rid of most of the built-ins. There's no way to get the contents of a String without use of built-ins, however, so string.toCharArray or string.charAt is required.