0

I am using this code:

    byte[] bytes = MESSAGE.getBytes();
    StringBuilder str = new StringBuilder();
    for (byte b : bytes) {
        int val = b;
        for (int i = 0; i < 8; i++) {
            str.append((val & 128) == 0 ? 0 : 1);
            val <<= 1;
        }
    }

and I'm trying to modify it to remove leading zerosfrom the binary code of every ASCII character before it gets appended to binary StringBuilder str. But the problem is the number of leading zeros is unknown and I can only remove them from the entire binary block by adding the following after the first block:

    String MSG = "";
    for(int i = 0; i < str.length(); i++) {
        if(str.charAt(i) == '0')
            MSG = (str.toString()).substring(i+1,str.length());
        else
            break;
    }

Any ideas?

3
  • What are you trying to do? Commented Aug 5, 2015 at 20:44
  • She doesn't want the leading zeroes, because now she has to remove them when she uses her string printing method. Commented Aug 5, 2015 at 20:45
  • @brso05 I'm trying to remove the leading zeros of every character before appending their binaries together here: str.append((val & 128) == 0 ? 0 : 1); Commented Aug 5, 2015 at 20:49

5 Answers 5

4

Integer.toBinaryString(yourByte).replaceFirst("0*", "");

A more complete example would be.

final StringBuilder builder = new StringBuilder();
String example = "A test string";

for( byte b: example.getBytes()){
    builder.append(Integer.toBinaryString(b).replaceFirst("0*",""));
}   

System.out.println(builder.toString());
Sign up to request clarification or add additional context in comments.

4 Comments

She only wants to remove leading zeroes until a 1 is found. Leading zeroes of bytes after that are not to be removed because they have a leading 1 from a previous byte.
I don't know what you are saying. You can give it a shot. ideone.com/AVZc4r
"001001" should be converted to "1100000011000000110001001100000011000000110001", which is the binary representation of the ASCII codes of that string (0 is 00110000 and 1 is 00110001). Your code converts it to "1001"
My code is only to convert a byte, and I provided an example of the byte conversion. Not taking "001001" as a string but showing that any byte string will have only the leading zeros removed. eg. The code I pasted above will turn a byte into a string of 0's and 1's then remove the leading zeros.
3

How about this:

byte[] bytes = MESSAGE.getBytes();
StringBuilder str = new StringBuilder();
for (byte b : bytes) {
    int val = b;
    boolean dontWriteYet = true;
    for (int i = 0; i < 8; i++) {
        int digit = (val & 128) == 0 ? 0 : 1;
        if(digit == 1 && dontWriteYet ) {
            dontWriteYet = false;
        } 
        if (!dontWriteYet) {
            str.append(digit);
        }
        val <<= 1;
    }
    //if all 0's then we must add the 0
    if (dontWriteYet){
        str.append(0);
    }
}

Basically do not write to str until you get a 1. Once you get a 1, then write the rest.

EDITTED code to add case where all 0's.

1 Comment

ah yes, looks like we had the same idea, but executed it slightly different.
2

It does look complicated, because you use the ternary operator, but it is actually not that hard to modify the code to omit leading zeroes:

byte[] bytes = MESSAGE.getBytes();
StringBuilder str = new StringBuilder();
boolean first = true;
for (byte b : bytes) {
    int val = b;
    for (int i = 0; i < 8; i++) {
        int v = (val & 128) == 0 ? 0 : 1;
        if (v == 1 || !first || i == 7) {
            str.append(v);
            first = false;
        }
        val <<= 1;
    }
}

1 Comment

great minds think alike. though matt's solution is pretty slick.
1

Easiest solution is to use a flag to mark when you find a 1 and only add characters when such flag is true. That solution has one inconvenient, you have to check that flag EACH time. A more efficient solution would be to have different code for traversing zeroes and for adding characters :

static class Indexes {

    int indexByte;
    int indexBit;
}

static void traverseZeroes(byte[] bytes, Indexes indexes) {
    for (indexes.indexByte = 0; indexes.indexByte < bytes.length; ++indexes.indexByte) {
        int val = bytes[indexes.indexByte];
        for (indexes.indexBit = 0; indexes.indexBit < 8; ++indexes.indexBit) {
            if ((val & 128) != 0) {
                return;
            }
            val <<= 1;
        }
    }
}

static void addBits(byte[] bytes, Indexes indexes, StringBuilder str) {
    if ( indexes.indexByte>=bytes.length ) {
        str.append('0');
        return;
    }
    int val = bytes[indexes.indexByte] << indexes.indexBit;
    for (;;) {
        while (indexes.indexBit < 8) {
            str.append((val & 128) == 0 ? 0 : 1);
            val <<= 1;
            ++indexes.indexBit;
        }
        indexes.indexBit = 0;
        ++indexes.indexByte;
        if (indexes.indexByte >= bytes.length) {
            break;
        }
        val = bytes[indexes.indexByte];
    }
}

public static void main(String[] args) {
    byte[] bytes = MESSAGE.getBytes();
    StringBuilder str = new StringBuilder();
    Indexes indexes = new Indexes();
    traverseZeroes(bytes, indexes);
    addBits(bytes, indexes, str);
    System.out.println(str);
}

In the unlikely case that perfomance is important enough use that. Otherwise use the flag.

2 Comments

You only have to check the flag on 0s, so before you find the first 1 this idea is roughly the same and then it gets better. Also I think it's better to use 0 or '0' so no object gets created. Otherwise I agree.
True, I've changed "0" to '0'.
0

Could you start with the ASCII code as an Integer and then call .toBinaryString() on that? I think that would get rid of the zeros. Docs are here if it helps.

To get an Integer value you can just cast directly from the character.

public String characterToBinary(char c){
    int ascii = (int) c;
    return Integer.toBinaryString(ascii);
}

If it's an Integer you also have access to other useful methods like .numberOfLeadingZeros().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.