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

자바는 unsigned 형이 없음.

자바백서에 나왔던가 어디선가 봤는데 넣으면 복잡해진다고 기본 자료형에서 unsigned 형을 빼버렸음.
뭐 좋긴한데 자바만 쓸때 이야기고 다른 플랫폼이랑 데이터 송수신 하다 보면 unsigned 형은 필요할때가 종종 있음.

signed 형 범위 안에서만 데이터가 왔다갔다 한다면 별 상관없겠지만 현실은 그리 만만하지 않음.
언제 뭐가 올지 모르니 거기에 대비해야 함.

오늘의 경우는 장비로 부터 데이터가 byte로 넘어오는데  장비는 unsigned 타입의 데이터를 byte로 변환해서 넘겨줌.
장비도 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
--------------------------------------

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


크리에이티브 커먼즈 라이선스Linsoo의 저작물인 이 저작물은(는)크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.

댓글 남기기

이메일은 공개되지 않습니다.

This site uses Akismet to reduce spam. Learn how your comment data is processed.