[java] Java에서 바이트 배열을 정수로 변환하거나 그 반대로 변환

Java에서 바이트 배열에 일부 데이터를 저장하고 싶습니다. 기본적으로 숫자 당 최대 2 바이트를 사용할 수있는 숫자입니다.

정수를 2 바이트 길이의 바이트 배열로 변환하거나 그 반대로 변환하는 방법을 알고 싶습니다. 인터넷에서 많은 솔루션을 찾았지만 대부분 코드에서 일어나는 일을 설명하지 않습니다. 실제로 이해하지 못하는 많은 변화가 있기 때문에 기본 설명에 감사드립니다.



답변

java.nio네임 스페이스 에있는 클래스, 특히을 사용하십시오 ByteBuffer. 그것은 당신을 위해 모든 일을 할 수 있습니다.

byte[] arr = { 0x00, 0x01 };
ByteBuffer wrapped = ByteBuffer.wrap(arr); // big-endian by default
short num = wrapped.getShort(); // 1

ByteBuffer dbuf = ByteBuffer.allocate(2);
dbuf.putShort(num);
byte[] bytes = dbuf.array(); // { 0, 1 }


답변

byte[] toByteArray(int value) {
     return  ByteBuffer.allocate(4).putInt(value).array();
}

byte[] toByteArray(int value) {
    return new byte[] {
        (byte)(value >> 24),
        (byte)(value >> 16),
        (byte)(value >> 8),
        (byte)value };
}

int fromByteArray(byte[] bytes) {
     return ByteBuffer.wrap(bytes).getInt();
}
// packing an array of 4 bytes to an int, big endian, minimal parentheses
// operator precedence: <<, &, | 
// when operators of equal precedence (here bitwise OR) appear in the same expression, they are evaluated from left to right
int fromByteArray(byte[] bytes) {
     return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}

// packing an array of 4 bytes to an int, big endian, clean code
int fromByteArray(byte[] bytes) {
     return ((bytes[0] & 0xFF) << 24) |
            ((bytes[1] & 0xFF) << 16) |
            ((bytes[2] & 0xFF) << 8 ) |
            ((bytes[3] & 0xFF) << 0 );
}

부호있는 바이트를 int로 패킹 할 때 각 바이트는 산술 승격 규칙 (JLS, 변환 및 승격에 설명 됨)으로 인해 32 비트 (0 확장이 아닌)로 확장되므로 마스크 해제해야합니다.

Joshua Bloch와 Neal Gafter의 Java Puzzlers ( “모든 바이트에서 큰 기쁨”)에 설명 된 흥미로운 퍼즐이 있습니다. 바이트 값을 int 값과 비교할 때 바이트는 int로 부호 확장되고이 값은 다른 int와 비교됩니다.

byte[] bytes = (…)
if (bytes[0] == 0xFF) {
   // dead code, bytes[0] is in the range [-128,127] and thus never equal to 255
}

16 비트 부호없는 정수 유형 인 char을 제외하고 모든 숫자 유형은 Java로 서명됩니다.


답변

가변 길이 바이트에 BigInteger를 사용할 수도 있습니다. 필요에 따라 long, int 또는 short로 변환 할 수 있습니다.

new BigInteger(bytes).intValue();

또는 극성을 나타 내기 위해 :

new BigInteger(1, bytes).intValue();

바이트를 다시 얻으려면 :

new BigInteger(bytes).toByteArray()


답변

기본 구현은 다음과 같습니다.

public class Test {
    public static void main(String[] args) {
        int[] input = new int[] { 0x1234, 0x5678, 0x9abc };
        byte[] output = new byte[input.length * 2];

        for (int i = 0, j = 0; i < input.length; i++, j+=2) {
            output[j] = (byte)(input[i] & 0xff);
            output[j+1] = (byte)((input[i] >> 8) & 0xff);
        }

        for (int i = 0; i < output.length; i++)
            System.out.format("%02x\n",output[i]);
    }
}

내용을 이해하기 위해이 WP 기사를 읽을 수 있습니다 : http://en.wikipedia.org/wiki/Endianness

위의 소스 코드가 출력 34 12 78 56 bc 9a됩니다. 처음 2 바이트 ( 34 12)는 첫 번째 정수 등을 나타냅니다. 위의 소스 코드는 작은 엔디안 형식의 정수를 인코딩합니다.


답변

/** length should be less than 4 (for int) **/
public long byteToInt(byte[] bytes, int length) {
        int val = 0;
        if(length>4) throw new RuntimeException("Too big to fit in int");
        for (int i = 0; i < length; i++) {
            val=val<<8;
            val=val|(bytes[i] & 0xFF);
        }
        return val;
    }


답변

비트에서 읽어야하는 요구 사항이있는 사람은 3 비트 만 읽어야하지만 부호있는 정수가 필요하다고 말하면 다음을 사용하십시오.

data is of type: java.util.BitSet

new BigInteger(data.toByteArray).intValue() << 32 - 3 >> 32 - 3

매직 번호 는 사용중인 비트3 수가 아닌 바이트 수로 대체 될 수 있습니다 .


답변

구아바 에는 종종 필요한 것이 있습니다.

바이트 배열에서 int로 이동하려면 Ints.fromBytesArraydoc here

int에서 바이트 배열로 이동하려면 : Ints.toByteArraydoc here