2016-12-26 4 views
1

Мне нужно преобразовать число в массив байтов, а затем вернуться к номеру. Проблема заключается в том, что массив байт переменной размера, так что мне нужно, чтобы преобразовать число, учитывая его длину байт, методы, которые я придумал таковы: (Java)массив байтов с переменной длиной до номера

private static byte[] toArray(long value, int bytes) { 
    byte[] res = new byte[bytes]; 

    final int max = bytes*8; 
    for(int i = 1; i <= bytes; i++) 
     res[i - 1] = (byte) (value >> (max - 8 * i)); 

    return res; 
} 

private static long toLong(byte[] value) { 
    long res = 0; 

    for (byte b : value) 
     res = (res << 8) | (b & 0xff); 

    return res; 
} 

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

EDIT: чтобы проверить это, я попытался с обработкой значение Integer.MIN_VALUE + 1 (-2147483647) и 4 байта

+0

Dunno, если проблема решена сейчас, но ... Посмотрите, помогает ли мой ответ с обработкой l arge отрицательные значения. –

ответ

1

После принятия этого в качестве рабочего раствора, то Аскер сделал некоторые дополнительные оптимизации .
я включил свои собственные
linked codeниже справки:

private static long toLong(byte[] value) { 
    ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES); 
    final byte val = (byte) (value[0] < 0 ? 0xFF : 0); 

    for(int i = value.length; i < Long.BYTES; i++) 
     buffer.put(val); 

    buffer.put(value); 
    return buffer.getLong(0); 
} 

СТАРШЕ ОТВЕТ

редактировать: на основе комментариев (понимание Вопрос лучше)

К сделайте свой toLong функции обрабатывать оба отрицательных & положительных номера попробовать это:

private static long toLong(byte[] value) 
{ 
    long res = 0; 
    int tempInt = 0; 
    String tempStr = ""; //holds temp string Hex values 

    tempStr = bytesToHex(value); 

    if (value[0] < 0) 
    { 
     tempInt = value.length; 
     for (int i=tempInt; i<8; i++) { tempStr = ("FF" + tempStr); } 

     res = Long.parseUnsignedLong(tempStr, 16); 
    } 
    else { res = Long.parseLong(tempStr, 16); } 

    return res; 

} 

Ниже связана bytesToHex функции (повторно учитываться для работы вне коробки с любым byte[] входом ...)

public static String bytesToHex(byte[] bytes) 
{ String tempStr = ""; tempStr = DatatypeConverter.printHexBinary(bytes); return tempStr; } 


+1

Это не переменная, я не могу сказать «поместить это число в 5 байтов» или «получить мой номер из этих 5 байтов», – SnowyCoder

+0

Вы не должны вставлять только 5 байтов. Все языки/ОС читаются как 1, 2, 4 или 8 байтов одновременно.Если вашему номеру требуется только 5 байтов, вы уже находитесь в ситуации, когда вы действительно должны читать 8 байтов. Используйте [** бит-сдвиг **] (http://stackoverflow.com/a/141873/2057709), чтобы сохранить 40 бит (5 байтов) на одной стороне массива и заполнить оставшиеся 3 байтовых слота нулевыми битами. –

+0

Я уже делал что-то вроде этого (см. Мой вопрос), но проблема в том, что я не знаю, как бороться с отрицательными значениями. – SnowyCoder

1

Взгляните на Apache Common Conversion.intToByteArray метод Util.

JavaDoc:

Преобразует Int в массив байтов, используя по умолчанию (прямой порядок байтов, Lsb0) байт и бит заказа

+0

Просто протестировано: – SnowyCoder

+0

'long v = Integer.MIN_VALUE + 1; байт [] res = новый байт [4]; longToByteArray (v, 0, res, 0, 4); long out = byteArrayToLong (res, 0, 0L, 0, 4); System.out.println (out); 'negativity lost – SnowyCoder

+0

@SnowyCoder, если этот ответ работает, затем отметьте его как решение, используя значок' ✓'. –