Java - 将 ASCII 转换为不带前导零的二进制

Java - Converting ASCII to Binary without leading zeros

我正在使用此代码:

    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;
        }
    }

我正在尝试修改它以在每个 ASCII 字符的二进制代码附加到二进制 StringBuilder str 之前从其二进制代码中删除前导零。但问题是前导零的数量是未知的,我只能通过在第一个块之后添加以下内容来从整个二进制块中删除它们:

    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;
    }

有什么想法吗?

您能否以 Integer 的 ASCII 代码开始,然后在其上调用 .toBinaryString()?我认为这将摆脱零。 Docs are here if it helps.

要获得 Integer 值,您可以直接从角色中施​​放。

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

如果它是 Integer,您还可以使用其他有用的方法,例如 .numberOfLeadingZeros()

这个怎么样:

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);
    }
}

基本上在得到1之前不要写str。一旦得到1,然后写其余的。

编辑代码以添加全 0 的大小写。

它看起来确实很复杂,因为您使用了三元运算符,但实际上修改代码以省略前导零并不难:

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;
    }
}

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

一个更完整的例子是。

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());

最简单的解决方案是在找到 1 时使用标志进行标记,并且仅在该标志为真时才添加字符。该解决方案有一个不便之处,您必须每次都检查该标志。一个更有效的解决方案是使用不同的代码来遍历零和添加字符:

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);
}

在不太可能的情况下,性能足够重要,请使用它。否则使用标志。