Преобразование байта [] в строку, а затем обратно в байт [] - PullRequest
7 голосов
/ 03 мая 2010

Я работаю на прокси-сервере. Я получаю данные в byte[], которые я конвертирую в String для выполнения определенных операций. Теперь, когда я конвертирую этот новый String обратно в byte[], это вызывает неизвестные проблемы.

Так что, в основном, мне нужно знать, как правильно преобразовать byte[] в String и затем снова в byte[].

Я попытался просто преобразовать byte[] в String, а затем обратно в byte[] (чтобы убедиться, что это не мои операции, которые вызывают проблемы).

Так это как:

// where reply is a byte[]

String str= new String(reply,0, bytesRead);
streamToClient.write(str.getBytes(), 0, bytesRead);

не эквивалентно

streamToClient.write(reply, 0, bytesRead);

мой прокси работает нормально, когда я просто отправляю byte[] без преобразования, но когда я конвертирую его из byte[] в String, а затем обратно в byte[], это вызывает проблемы.

Может кто-нибудь, пожалуйста, помогите? =]

Ответы [ 4 ]

9 голосов
/ 03 мая 2010

Лучший способ преобразовать byte[] в String и обратно в byte[] - это вообще не делать этого.

Если необходимо, вы должны знать кодировку, которая использовалась для создания byte[], в противном случае операция использует кодировку платформы по умолчанию, которая может повредить данные, поскольку не все кодировки могут кодировать все возможные строки, и не все возможные последовательности байтов допустимы во всех кодировках. Это то, что происходит в вашем случае.

Что касается того, как узнать кодировку, это зависит:

  • Если вы используете HTTP, посмотрите заголовок Content-Type
  • Если ваши данные в формате XML, вы должны использовать синтаксический анализатор XML, который будет обрабатывать кодировку для вас
  • Если ваши данные представляют собой HTML-страницы, возможно, имеется также заголовок <meta http-equiv>

Если нет способа узнать кодировку , у вас есть случайный мусор, а не текстовые данные .

4 голосов
/ 22 июля 2016

Если это байтовый массив со знаком, то самое простое решение, которое я нашел, было закодировать байтовый массив с помощью BASE64EncoderStream, который преобразует его в байты без знака. Затем вам придется использовать BASE64DecoderStream для декодирования байтов, чтобы получить исходный подписанный байтовый массив.

Зависимость POM для BASE64: com.sun.mail javax.mail 1.4.4

public class EncryptionUtils {

private static String ALGO = "AES";
private static  Cipher cipher;




public static String encrypt(String message, String keyString) {
    cipher = Cipher.getInstance(ALGO);
        Key key = generateKey(keyString);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return new String(BASE64EncoderStream.encode(cipher.doFinal( message.getBytes())));
}

public static String decrypt(String message, String keyString)  {

       cipher = Cipher.getInstance(ALGO);
        Key key = generateKey(keyString);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(BASE64DecoderStream.decode(message.getBytes()))); 

}

private static Key generateKey(String keyString) throws NoSuchAlgorithmException {
    byte[] keyBytes = BASE64DecoderStream.decode(keyString.getBytes());
    Key key = new SecretKeySpec(keyBytes, ALGO);
    return key;
}

public static void main(String args[]) {
    byte[] keyValue = new byte[16];
    new SecureRandom().nextBytes(keyValue);
    String key = new String(BASE64EncoderStream.encode(keyValue));
    String message = "test message";
    String enc = encrypt(message, key);
    String dec = decrypt(enc, key);
    System.out.println(dec);
}}
3 голосов
/ 03 мая 2010

Вам необходимо знать используемую кодировку символов, декодировать байты, используя ее, и перекодировать, используя ту же кодировку символов. Например:

String str = new String(reply, 0, Charset.forName("UTF-8"));
bytes[] out = str.getBytes(Charset.forName("UTF-8"));
streamToClient.write(bytes, 0, bytes.length);

Если не указано, Java использует кодировку символов по умолчанию, которая обычно является UTF-8 (она может даже быть обязательной как таковая), но HTML часто будет чем-то другим. Я подозреваю, что это твоя проблема.

0 голосов
/ 12 марта 2016

У меня похожая проблема при чтении из сокета и отправке в другой, но моя проблема заключалась в том, что я записывал вывод с помощью BufferedOutputStream, когда я изменяю это на поток вывода, он работает. Я думаю, что есть проблема с выходным потоком буфера.

String mensaje ="what I want to send";
String ip = "192.168.161.165";
int port =  2042;
tpSocket = new Socket(ip, port);
os = tpSocket.getOutputStream();
byte[] myBytes= mensaje.getBytes();
ByteArrayInputStream byarris = new ByteArrayInputStream(myBytes);
int resulta =0;
byte[] bufferOutput= new byte[1];
while((resulta = byarris.read(bufferOutput))!= -1) {
    os.write(bufferOutput);
}
...