Java byte -> int로 변환시 들어온 byte가 unsigned 형일 경우

자바는 unsigned 형이 없음.
자바백서에서 나왔는데 unsigned가 있으면 복잡해진다고 기본 자료형에서 빼버렸다고 함.
뭐 간결해지는건 좋긴 한데 자바만 쓸때 이야기고 다른 플랫폼이랑 데이터 송수신 하다 보면 unsigned형이 필요할때가 종종 있음.

작업하다 보니 장비가 데이터 넘기는데 unsigned 타입 데이터임.
장비 업체한테 signed로 넘기면 안될까요 라고 하고 싶지만 해줄리가 없지 ㅜ.ㅜ;

어쩔수 없지 어차피 데이터는 unsigned나 signed나 똑같은 비트로 들어와서 데이터 타입에 따라 인식하는거니 unsinged int는 long형으로 받아 처리하면 되고 unsigned short은 int형으로 받아서 처리하면 됨.

Long형은?… Long형 크기의 데이터가 들어오지 않길 빌어야지 뭐

암튼 여기에 아래와 같은 변환에 대해 클래스로 하나 만들어 뽑아놓음.
long -> byte
byte -> long
int -> byte
byte -> int
short -> byte
byte -> short
unsigned int -> byte
byte -> unsigned int
unsigned short -> byte
byte -> unsigned short

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class DataTypeConverter {
    private static ByteBuffer m_ByteBuffer = ByteBuffer.allocateDirect(8);

    //----------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------
    // long -> byte
    public static void LongToByte(long input, byte[] b, int offset, ByteOrder endian) {
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.putLong(input);
            m_ByteBuffer.position(0);
            for(int cnt=0; cnt<8; cnt++)
                b[offset+cnt] = m_ByteBuffer.get(cnt);
        }
    }

    //----------------------------------------------------------------------------------
    // byte -> long
    public static long ByteToLong(byte[] data, int offset, ByteOrder endian){
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.put(data,offset,8);
            m_ByteBuffer.position(0);
            return m_ByteBuffer.getLong();
        }
    }
    //----------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------


    //----------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------
    // int -> byte
    public static void IntToByte(int input, byte[] b, int offset, ByteOrder endian) {
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.putInt(input);
            m_ByteBuffer.position(0);
            for(int cnt=0; cnt<4; cnt++)
                b[offset+cnt] = m_ByteBuffer.get(cnt);
        }
    }

    //----------------------------------------------------------------------------------
    // byte -> int
    public static int ByteToInt(byte[] data, int offset, ByteOrder endian){
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.put(data,offset,4);
            m_ByteBuffer.position(0);
            return m_ByteBuffer.getInt();
        }
    }
    //----------------------------------------------------------------------------------
    // uint -> byte
    public static void UintToByte(long input, byte[] b, int offset, ByteOrder endian){
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.putLong(input);
            m_ByteBuffer.position(0);
            if(endian == ByteOrder.LITTLE_ENDIAN) {
                for(int cnt=0; cnt<4; cnt++)
                    b[offset+cnt] = m_ByteBuffer.get(cnt);
            }
            else{
                for(int cnt=0; cnt<4; cnt++)
                    b[offset+cnt] = m_ByteBuffer.get(cnt+4);
            }
            return;
        }
    }

    //----------------------------------------------------------------------------------
    // byte -> uint
    public static long ByteToUint(byte[] data, int offset, ByteOrder endian){
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.limit(8);
            if(endian == ByteOrder.LITTLE_ENDIAN) {
                m_ByteBuffer.put(data, offset, 4);
                m_ByteBuffer.putInt(0);
            }
            else{
                m_ByteBuffer.putInt(0);
                m_ByteBuffer.put(data,offset,4);
            }
            m_ByteBuffer.position(0);
            return m_ByteBuffer.getLong();
        }
    }
    //----------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------

    //----------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------
    // short -> byte
    public static void ShortToByte(short input, byte[] b, int offset, ByteOrder endian) {
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.putShort(input);
            m_ByteBuffer.position(0);
            for(int cnt=0; cnt<2; cnt++)
                b[offset+cnt] = m_ByteBuffer.get(cnt);
        }
    }
    //----------------------------------------------------------------------------------
    // byte -> short
    public static short ByteToShort(byte[] data, int offset, ByteOrder endian){
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.put(data,offset,2);
            m_ByteBuffer.position(0);
            return m_ByteBuffer.getShort();
        }
    }

    //----------------------------------------------------------------------------------
    // ushort -> byte
    public static void UshortToByte(int input, byte[] b, int offset, ByteOrder endian){
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.putInt(input);
            m_ByteBuffer.position(0);
            if(endian == ByteOrder.LITTLE_ENDIAN) {
                for(int cnt=0; cnt<2; cnt++)
                    b[offset+cnt] = m_ByteBuffer.get(cnt);
            }
            else{
                for(int cnt=0; cnt<2; cnt++)
                    b[offset+cnt] = m_ByteBuffer.get(cnt+2);
            }
            return;
        }
    }
    //----------------------------------------------------------------------------------
    // byte -> ushort
    public static int ByteToUshort(byte[] data, int offset, ByteOrder endian){
        synchronized (m_ByteBuffer){
            m_ByteBuffer.clear();
            m_ByteBuffer.order(endian);
            m_ByteBuffer.limit(4);
            if(endian == ByteOrder.LITTLE_ENDIAN){
                m_ByteBuffer.put(data, offset, 2);
                m_ByteBuffer.putShort((short) 0);
            }
            else{
                m_ByteBuffer.putShort((short) 0);
                m_ByteBuffer.put(data, offset, 2);
            }
            m_ByteBuffer.position(0);
            return m_ByteBuffer.getInt();
        }
    }
}

DataTypeConverter.java

사용법은 아래와 같음 (사용법이라기 보다 잘 돌아가는지 테스트 예제?)

Log.d(TAG,"--------------------------------------");
StringBuilder tmpSB = new StringBuilder();
byte [] tmp = new byte[8];
long input = 0;

// Long test
input = Long.MAX_VALUE-1000;
Log.d(TAG,"input(Long)="+input);
DataTypeConverter.LongToByte(input, tmp,0, ByteOrder.BIG_ENDIAN);
input = DataTypeConverter.ByteToLong(tmp,0,ByteOrder.BIG_ENDIAN);

tmpSB.append("[BIG_ENDIAN] long -> byte >> ");
for(int cnt =0; cnt<8; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[BIG_ENDIAN] byte -> long >> "+input);
tmpSB.delete(0, tmpSB.length());

DataTypeConverter.LongToByte(input, tmp,0, ByteOrder.LITTLE_ENDIAN);
input = DataTypeConverter.ByteToLong(tmp,0,ByteOrder.LITTLE_ENDIAN);

tmpSB.append("[LITTLE_ENDIAN] long -> byte >> ");
for(byte b : tmp)
	tmpSB.append(String.format("%02x ",b));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[LITTLE_ENDIAN] byte -> long >> "+input);
Log.d(TAG,"--------------------------------------");
tmpSB.delete(0, tmpSB.length());

//----------------------------------------------------------------------------------
//Int test
input = Integer.MAX_VALUE-1000;
Log.d(TAG,"input(int)="+input);
DataTypeConverter.IntToByte((int)input, tmp,0, ByteOrder.BIG_ENDIAN);
input = DataTypeConverter.ByteToInt(tmp,0,ByteOrder.BIG_ENDIAN);

tmpSB.append("[BIG_ENDIAN] int -> byte >> ");
for(int cnt =0; cnt<4; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[BIG_ENDIAN] byte -> int >> "+input);
tmpSB.delete(0, tmpSB.length());

DataTypeConverter.IntToByte((int)input, tmp,0, ByteOrder.LITTLE_ENDIAN);
input = DataTypeConverter.ByteToInt(tmp,0,ByteOrder.LITTLE_ENDIAN);

tmpSB.append("[LITTLE_ENDIAN] int -> byte >> ");
for(int cnt =0; cnt<4; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[LITTLE_ENDIAN] byte -> int >> "+input);
Log.d(TAG,"--------------------------------------");
tmpSB.delete(0, tmpSB.length());

//----------------------------------------------------------------------------------
// short test
input = Short.MAX_VALUE-10;
Log.d(TAG,"input(short)="+input);
DataTypeConverter.ShortToByte((short)input, tmp,0, ByteOrder.BIG_ENDIAN);
input = DataTypeConverter.ByteToShort(tmp,0,ByteOrder.BIG_ENDIAN);

tmpSB.append("[BIG_ENDIAN] short -> byte >> ");
for(int cnt =0; cnt<2; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[BIG_ENDIAN] byte -> short >> "+input);
tmpSB.delete(0, tmpSB.length());

DataTypeConverter.ShortToByte((short)input, tmp,0, ByteOrder.LITTLE_ENDIAN);
input = DataTypeConverter.ByteToShort(tmp,0,ByteOrder.LITTLE_ENDIAN);

tmpSB.append("[LITTLE_ENDIAN] short -> byte >> ");
for(int cnt =0; cnt<2; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[LITTLE_ENDIAN] byte -> short >> "+input);
Log.d(TAG,"--------------------------------------");
tmpSB.delete(0, tmpSB.length());

//----------------------------------------------------------------------------------
// uint test
input =(Integer.MAX_VALUE+(long)5000);
Log.d(TAG,"input(uint)="+Long.toString(input));
DataTypeConverter.UintToByte(input, tmp,0, ByteOrder.BIG_ENDIAN);
input = DataTypeConverter.ByteToUint(tmp,0,ByteOrder.BIG_ENDIAN);

tmpSB.append("[BIG_ENDIAN] uint -> byte >> ");
for(int cnt =0; cnt<4; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[BIG_ENDIAN] byte -> uint >> "+input);
tmpSB.delete(0, tmpSB.length());

DataTypeConverter.UintToByte((int)input, tmp,0, ByteOrder.LITTLE_ENDIAN);
input = DataTypeConverter.ByteToUint(tmp,0,ByteOrder.LITTLE_ENDIAN);

tmpSB.append("[LITTLE_ENDIAN] uint -> byte >> ");
for(int cnt =0; cnt<4; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[LITTLE_ENDIAN] byte -> uint >> "+input);
Log.d(TAG,"--------------------------------------");
tmpSB.delete(0, tmpSB.length());

//----------------------------------------------------------------------------------
// ushort test
input =(Short.MAX_VALUE+(long)100);
Log.d(TAG,"input(ushort)="+Long.toString(input));
DataTypeConverter.UshortToByte((int) input, tmp,0, ByteOrder.BIG_ENDIAN);
input = DataTypeConverter.ByteToUshort(tmp,0,ByteOrder.BIG_ENDIAN);

tmpSB.append("[BIG_ENDIAN] ushort -> byte >> ");
for(int cnt =0; cnt<2; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[BIG_ENDIAN] byte -> ushort >> "+input);
tmpSB.delete(0, tmpSB.length());

DataTypeConverter.UintToByte((int)input, tmp,0, ByteOrder.LITTLE_ENDIAN);
input = DataTypeConverter.ByteToUint(tmp,0,ByteOrder.LITTLE_ENDIAN);

tmpSB.append("[LITTLE_ENDIAN] uint -> byte >> ");
for(int cnt =0; cnt<2; cnt++)
	tmpSB.append(String.format("%02x ", tmp[cnt]));
Log.d(TAG, tmpSB.toString());
Log.d(TAG,"[LITTLE_ENDIAN] byte -> uint >> "+input);
Log.d(TAG,"--------------------------------------");
tmpSB.delete(0, tmpSB.length());
//----------------------------------------------------------------------------------

이걸 실행하면 아래와 같은 결과를 보여줌

--------------------------------------
input(Long)=9223372036854774807
[BIG_ENDIAN] long -> byte >> 7f ff ff ff ff ff fc 17 
[BIG_ENDIAN] byte -> long >> 9223372036854774807
[LITTLE_ENDIAN] long -> byte >> 17 fc ff ff ff ff ff 7f 
[LITTLE_ENDIAN] byte -> long >> 9223372036854774807
--------------------------------------
input(int)=2147482647
[BIG_ENDIAN] int -> byte >> 7f ff fc 17 
[BIG_ENDIAN] byte -> int >> 2147482647
[LITTLE_ENDIAN] int -> byte >> 17 fc ff 7f 
[LITTLE_ENDIAN] byte -> int >> 2147482647
--------------------------------------
input(short)=32757
[BIG_ENDIAN] short -> byte >> 7f f5 
[BIG_ENDIAN] byte -> short >> 32757
[LITTLE_ENDIAN] short -> byte >> f5 7f 
[LITTLE_ENDIAN] byte -> short >> 32757
--------------------------------------
input(uint)=2147488647
[BIG_ENDIAN] uint -> byte >> 80 00 13 87 
[BIG_ENDIAN] byte -> uint >> 2147488647
[LITTLE_ENDIAN] uint -> byte >> 87 13 00 80 
[LITTLE_ENDIAN] byte -> uint >> 2147488647
--------------------------------------
input(ushort)=32867
[BIG_ENDIAN] ushort -> byte >> 80 63 
[BIG_ENDIAN] byte -> ushort >> 32867
[LITTLE_ENDIAN] uint -> byte >> 63 80 
[LITTLE_ENDIAN] byte -> uint >> 32867
--------------------------------------

뭐 잘 돌아가는거 같으니 이만…


Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다