java socket tcp/ip基本数据类型编解码【高序字节 低序字节】

package com.learning.forsocket.decodeencode;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

/*
* 一下代码是根据java socket tcp/ip编程书籍中对基本类型编码例子添加相关自己注释以及理解
*
*因主机CPU不同,不同的机器会出现高、低两种字节序问题
*Little endian:将低序字节存储在起始地址
*Big endian:将高序字节存储在起始地址
* JAVA是网络字节序 字节存储高字节序
*java中提供相应的方法 也可以通过移位来实现【列子中是高字节位存储例子可以通过修改顺序实现Little endian】
*
*/
public class BruteForceCoding {
private static byte byteVal = 101;
private static short shortVal = 10001;
private static int intVal = 100000001;
private static long longVal = 1000000000001L;

/**
 * byte short int long 类型占用几个字节
 * */
private final static int BSIZE = Byte.BYTES;
private final static int SSIZE = Short.BYTES;
private final static int ISIZE = Integer.BYTES;
private final static int LSIZE = Long.BYTES;

/*******
 * 定义整数进行将无符号转成有符号的数据进行扩展位使用【主要针对一个字节来输出数据,方便观察数据】
 *
 */
private final static int BYTEMASK = 0xFF;

/***
 * 此方法的是将一个字节数据的数据以无符号十进制数据展示,主要方便我们观察存储数据
 *
 * **/
public static String byteArrayToDecimalString(byte[] bArray) {
    StringBuilder rtn=new StringBuilder();
    for (byte b : bArray) {
        rtn.append(b&BYTEMASK).append(" ");
        /***
         * 这块的逻辑【有符号转负】:比如-128的数据【补码】  10000000--》-128的扩展为是11111111  11111111  11111111  10000000  与 00000000 00000000
         * 00000000 11111111 做&运算   00000000 00000000  00000000 1000000--->即是128 -127-->对应129
         * 也可以这样简单理解:1个字节 -128-127   如果变成无符号的一个字节大小就是0-255 由于数据数据是周期性127之后就是-128对应129 ...-1就是255
         */

    }

    return rtn.toString();
}

/****
 *
 * @param dst 字节数组
 * @param val 数据
 * @param offset 存的偏移量
 * @param size   存放几个字节
 * @return
 */
public static  int encodeIntBigEndian(byte[]dst,long val,int offset,int size){

    for (int i = 0; i < size; i++) {
        //字节数组先存高位然后地位字节
        dst[offset++]= (byte) (val>>((size-i-1)*Byte.SIZE));
    }

    return offset;//返回的数据表示字节数据的位置
}

/**
 *
 * @param val 字节数据
 * @param offset 读取的开始字节数组位置
 * @param size 几个字节
 * @return
 */
public static long decodeIntBigEndian(byte[] val,int offset,int size){
    long rtn=0;
    for (int i = 0; i < size; i++) {
        /**
         *处理方式方式:第一次rtn=0,假设取两个字节 offset=1
         * 首先去val[offset],第二个字节,首先rtn左移动8位,然后取val[offset+1] 取最后8位 做|运算
         * 其他的计算依然如此
         */
        rtn=(rtn<<Byte.SIZE)|((long)val[offset+i]&BYTEMASK);

    }
    return rtn;

}

/***
 * 将有符号的字节转成int
 * @param data
 * @return
 */
public static int getUnsignedByte (byte data){
    return data&0x0FF ;
}

public static void main(String[] args) throws Exception {
    //

// byte sortdata=-1;
// System.out.println(getUnsignedByte(sortdata));

    //定义一个字节数据
    byte[] mesage=new byte[BSIZE+SSIZE+ISIZE+LSIZE];//1+2+4+8  15个字节

    //编码 分别将 byte short int long类型的数据写入字节数据【超过1一个字节的数据类型  高位在前 低位在后】
    int offset=encodeIntBigEndian(mesage,byteVal,0,BSIZE);
    offset=encodeIntBigEndian(mesage,shortVal,offset,SSIZE);
    offset=encodeIntBigEndian(mesage,intVal,offset,ISIZE);
    offset=encodeIntBigEndian(mesage,longVal,offset,LSIZE);
    System.out.println("Encode message:"+byteArrayToDecimalString(mesage));


    //解码
    long value=decodeIntBigEndian(mesage,0,BSIZE);
    System.out.println("Docoded byte="+value);

    value=decodeIntBigEndian(mesage,BSIZE,SSIZE);//从下标是1的位置开始读取2个字节
    System.out.println("Docoded short="+value);

    value=decodeIntBigEndian(mesage,3,ISIZE);//从下标是1的位置开始读取2个字节
    System.out.println("Docoded int="+value);

    value=decodeIntBigEndian(mesage,BSIZE+SSIZE+ISIZE,LSIZE);//从下标是7的位置开始读取8个字节
    System.out.println("Docoded long="+value);


    offset=4;
    value=decodeIntBigEndian(mesage,offset,BSIZE);//表示取第五个字节取一个字节  245
    System.out.println("Decoded value(offset "+offset+",size "+BSIZE+")="+value);

    byte bVal=(byte)decodeIntBigEndian(mesage,offset,BSIZE);//-11
    System.out.println("Same value as byte="+bVal);

    /*java提供原声方法进行输出【高序字节】*/
    ByteArrayOutputStream buf=new ByteArrayOutputStream();
    DataOutputStream out=new DataOutputStream(buf);
    out.writeByte(byteVal);
    out.writeShort(shortVal);
    out.writeInt(intVal);
    out.writeLong(longVal);
    out.flush();
    byte[] msg=buf.toByteArray();
    System.out.println("Encode message:"+byteArrayToDecimalString(msg));
}

}

===========================================================
Java提供的方法也是通过移位来实现的,debug跟进可以看到:
这里写图片描述这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值