如何设计基于字节码的报文或传输协议
任何数据在计算机的存储形式为0或1(二进制),计算机将这些数据存储于硬盘/内存/寄存器等存储空间中,cpu将指定位置指定长度的二进制数据进行位运算以得到结果
- 二进制 二进制是由1和0两个数字组成的,它可以表示两种状态,即开和关.所有输入电脑的任何信息最终都要转化为二进制, 最基本的单位为bit.
- 位运算 程序中的所有数在计算机内存中都是以二进制的形式储存;位运算是指将这些二进制数据按位进行运算,位运算的运算符包括:
运算符 | 意义 | 例子 |
---|---|---|
<< | 右移(各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)) | 0011 << 1 = 0110 |
>> | 左移(各二进位全部左移若干位,高位丢弃,低位补0) | 0011 >> 1 = 0001 |
& | 与(两个位都为1时,结果才为1) | 0111 & 1100 = 0100 |
| | 或(两个位都为0时,结果才为0) | 0011 | 1011 = 1011 |
^ | 异或(两个位相同为0,相异为1) | 0011 ^ 1010 = 1001 |
~ | 取反(0变1,1变0) | ~0011 = 1100 |
数据结构 | 大小 | 取值范围 |
---|---|---|
Bit | 比特,一位二进制数(0/1表示) | 0 ~ 1 |
Byte | 字节,8 Bit, 8位二进制数 | -128 ~ 127 |
Short | 短整型,2 Byte(字节),16位二进制数 | -32768 ~ 32767 |
Int | 整型,4 Byte(字节),32位二进制数 | -2,147,483,648 ~ 2,147,483,647 |
Long | 长整型,8 Byte(字节), 64位二进制数 | -9223372036854775808 ~ 9223372036854775807 |
Float | 单精度浮点数,4 Byte(字节) 32 位 | 1.4E-45 ~ 3.4028235E38 |
Double | 双精度浮点数,8 Byte(字节) 64位 | 4.9E-324 ~ 1.7976931348623157E308 |
Char | 字符, 2个字节,16位 | - |
Boolean | Doesn't have a defined byte size | - |
*Float & Double 存储时是以科学计数方式存储(存储底数和幂) 所以通常在表示带小数点报文时,将整数部分,和小数部分进行分割,明确字段的保留精度(例如保留小数点后6位);将两部分根据取值范围分别存储与单个或多个字节中。
- 二进制
- 4 进制
- 8 进制
- 10 进制
- 16 进制 :(Hex)16进制由数字和字母来表示: 1-10 -> 1-10 , A B C D E -> 11 12 13 14 15
这里着重介绍16进制,因为通常都是基于十六进制来设计协议
一个十六进制数占四位,也就是半个字节 通常报文的数据单位用字节为最小单位来设计,也就是两位十六进制数;也可以以其他单位大小来设计报文。
- 0x 在代码语言中以0x来表示16进制,例如0xAC, 表示两位十六进制数(AC),占一个字节,十进制等于172。
- Hex String 由于有字母有数字,可以在log或者其他需要显示的地方更清晰更短的显示,所以在展示是以字符串来展示16进制数
通常编写业务代码时我们需要使用10进制数,进行通讯时我们使用Hex进行设计,进行编码时我们以0x来表示16进制
计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。
字节顺序从左往右数起,从0开始。各类数据结构均可以通过BE/LE来表示 例:0x1100使用两个字节储存:高位字节是0x11,低位字节是0x00。
- 大端字节序:高位字节在前,低位字节在后,即以0x1100。
- 小端字节序:低位字节在前,高位字节在后,即以0x0011形式储存。
BitMask在计算机学中指的是一串二进制数字,通过与目标数字的按位操作,达到屏蔽指定位的目的。BitMask采用数值记录状态,每一个bit有两种取值,即0和1,数值的每一位表示一个状态。使用BitMask可以用很少的资源表达非常丰富的状态。在 Java 中,一個 byte 型的数组,有 8 位(bit),可以表达 8 个不同的状态,而且这些状态并不会相互影响。对于int,则32位,即可以表达32种状态。使用掩码,可以在单个按位操作中将字节,半字节,字等中的多个位设置为打开,关闭或从打开反转为关闭(反之亦然)。
Hex string to Int
String.toInt(radix: Int = 16)
Int to Hex String
String.toHexString(int i)
Int to Hex String with format
String.format("%02x", int)
以十六进制输出,2为指定的输出字段的宽度.如果位数小于2,则左端补0
Byte to Int
it.toInt() & 0xFF
todo why?????