2015-08-05 4 views
0

Я использую этот код:Java - Преобразование ASCII в двоичный без ведущих нулей

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

и я пытаюсь изменить его, чтобы удалить ведущие zerosfrom двоичного кода каждого символа 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; 
    } 

Есть идеи?

+0

Что вы пытаетесь сделать? – brso05

+0

Она не хочет ведущих нулей, потому что теперь она должна удалить их, когда она использует свой метод струйной печати. –

+0

@ brso05 Я пытаюсь удалить ведущие нули каждого символа перед добавлением их двоичных файлов вместе: 'str.append ((val & 128) == 0? 0: 1);' – SalmaFG

ответ

4

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

slick .......... –

+0

Она только хочет удалить ведущие нули до тех пор, пока не будет найдено 1. Ведущие нули байтов после этого не подлежат удалению, поскольку они имеют ведущий 1 из предыдущего байта. –

+0

Я не знаю, что вы говорите. Вы можете дать ему шанс. Http: // ideone.com/AVZc4r – matt

0

Не могли бы вы начать с кода ASCII как Integer, а затем позвонить .toBinaryString()? Я думаю, что избавится от нулей. Docs are here if it helps.

Чтобы получить значение Integer, вы можете просто отличить его непосредственно от персонажа.

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

Если это Integer у вас также есть доступ к другим полезным методам, таким как .numberOfLeadingZeros().

3

Как об этом:

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. После того, как вы получите 1, а затем записать все остальное.

EDITTED код для добавления случая, где все 0.

+0

@maraca отличный момент, позвольте мне исправить это –

+0

ах да, похоже, у нас была такая же идея, но она была немного иной. – maraca

+0

Это работает. Благодаря! – SalmaFG

2

Это выглядит сложным, потому что вы используете тройной оператор, но это на самом деле не так уж трудно изменить код, чтобы пропустить начальные нули:

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

великие умы думают одинаково. хотя решение мата довольно гладкое. –

1

Самое простое решение - использовать флаг для отметки, когда вы найдете 1 и добавляете только символы, когда этот флаг является истинным. У этого решения есть одно неудобное, вы должны проверить этот флаг EACH time. Более эффективное решение будет иметь разный код для обхода нулей и для добавления символов:

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

В маловероятном случае, что Perfomance важно достаточно использовать. В противном случае используйте флаг.

+0

Вам нужно только проверить флаг на 0s, поэтому, прежде чем вы найдете первый 1, эта идея примерно такая же, а затем она становится лучше. Также я думаю, что лучше использовать 0 или «0», поэтому объект не создается. В противном случае я согласен. – maraca

+0

Верно, я изменил «0» на «0». –

Смежные вопросы