2015-12-27 4 views
0

Я переношу некоторый PHP-код, а также код python, которые являются двумя функциями. Их цель состоит в анализе целого числа на массив байтов и наоборот. Однако это сработало некоторое время, но теперь я получаю недопустимые целочисленные ошибки.Java - byte [] to int conversion и наоборот

я получил следующий питона фрагмент кода, который я преобразован в Java:

def _deAdjustId(val): 
    if sys.version_info >= (3,0): 
     valEnc = val.encode('latin-1') if type(val) is str else val 
    else: 
     valEnc = val 
    return int(binascii.hexlify(valEnc), 16) 

И мой код Java:

private static int deAdjustId(byte[] val) { 
    String valEnc; 
    try { 
     valEnc = new String(val, "iso-8859-1"); 
    } catch (UnsupportedEncodingException e) { 
     valEnc = new String(val); 
    } 
    return Integer.parseInt(BinAscii.hexlify(valEnc.getBytes()), 16); 
} 

Ошибка Приведенное здесь следующее:

caught exception: Invalid int: "325FC398C3AB" 

Означает ли это, что целочисленное значение слишком велико или в чем проблема?

+1

Java ИНТ 32-разрядный. Это более 4 байтов. –

ответ

0

Python int, как BigInteger в Java:

private static BigInteger deAdjustId(byte[] val) { 
    String valEnc; 
    try { 
     valEnc = new String(val, "iso-8859-1"); 
    } catch (UnsupportedEncodingException e) { 
     valEnc = new String(val); 
    } 
    return new BigInteger(BinAscii.hexlify(valEnc.getBytes()), 16); 
} 

или даже:

private static BigInteger deAdjustId(byte[] val) { 
    return new BigInteger(val); 
} 
+0

Хорошо спасибо! но возвращаемый тип должен быть зашифрованным int и всем, см. здесь: https://github.com/gi097/WhatsApi-Android/blob/1287cd3fc5619b760433bdcddb0d083aa4f3ce45/app/src/main/java/nl/giovanniterlingen/whatsapp /WhatsApi.java См. Последние два метода. –

+0

@JohnDoe Но тогда размер массива не может превышать 4 байта, что он, очевидно, делает в вашем случае ... – glglgl

1

valEnc.getBytes() преобразует строку в байты, используя кодировку по умолчанию хост-платформы, которая собирается быть UTF -16LE (в Windows) или UTF-8 (все другие платформы, включая ваши).

Ваша строка содержит символы ISO 8859-1, но любой из этих символов со значениями выше 127 составляет , декодированный как несколько байтов на valEnc.getBytes(). Чтобы исправить это, используйте valEnc.getBytes(StandardCharsets.ISO_8859_1). Тогда вам гарантированно получить один байт за персонажа.

Тем не менее, возникает вопрос о том, почему вы должны были бы использовать String в первую очередь. У вас уже есть массив байтов, чьи байты представляют собой символ ISO 8859-1. Вы должны полностью удалить valEnc.

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

return ByteBuffer.wrap(val).getInt(); 

Смотрите documentation for ByteBuffer для получения дополнительной информации, в частности, методы getInt.

Обновление: кажется val не имеет никаких гарантий относительно ее размера, так что вы хотите, чтобы учесть, что:

if (val == null) { 
    return 0; 
} 

if (val.length >= 4) { 
    return ByteBuffer.wrap(val).getInt(); 
} 

ByteBuffer buffer = ByteBuffer.allocate(4); 
buffer.position(4 - val.length); 
buffer.put(val); 
buffer.rewind(); 
return buffer.getInt(); 
+0

Ну, это дает мне BufferUnderflowException ... Может быть, вы можете посмотреть здесь, это был рабочий код, но это один больше не работал после того, как были незаконные символы, которые не могли быть проанализированы в int https: // github.com/gi097/WhatsApi-Android/blob/1287cd3fc5619b760433bdcddb0d083aa4f3ce45/app/src/main/java/nl/giovanniterlingen/whatsapp/WhatsApi.java –

+0

Ошибка BufferUnderflowException должна произойти только в том случае, если ваш массив имеет менее 4 байтов. Для этого я обновил свой ответ. – VGR

+0

Действительно полезно! Спасибо. А как насчет обратного порядка? От int обратно к исходному массиву byte []? ByteBuffer тоже может справиться? –