前言:本篇文章是对于基础数据的处理的一些简单经验总结里边包含了一些基础的数据储存和数据转化的一些知识,同样也包含有部分快捷的数据处理方法。主要用于个人知识的一个记录和方便进行对应的数据转换和处理。
1、bit,字节和字的关系
1.1 bit和字节的互相转化
比特的基础定义
-
比特
-
表示二进制位
-
11010100是一个8位二进制数
-
计算机存储信息的最小单位
字,字节和位的关系
-
1位=1比特
-
1Byte=8bit
-
1字=2字节
-
1字节=8位
-
1字=16位
bit和字节的转化实例
bit和字节在转化时往往有些分不清具体bit是如何计算位数的,故留此图做分辨
bit和字节互相转化的代码
bit和字节其实可以通过Integer的toBinaryString和toHexString进行16进制和二进制的互相转化,但为了能在程序中便捷的操作每个bit位,故总结了以下方法实现16进制字符串转化为2进制字符串
/**
* 16进制字符转化为二进制字符串
* @param hex
* @return String
*/
public static String hexStringToBitString(String hex) {
byte[] bytes = hexStr2Byte(hex);
return byteToBitString(bytes);
}
public static String byteToBitString(byte[] bytes) {
String res = "";
for (Byte aByte : bytes) {
String binaryString = Integer.toBinaryString(aByte);
int length = binaryString.length();
if (length < 8) {
for (int i = 0; i < 8 - length; i++) {
binaryString = "0" + binaryString;
}
}
res = binaryString.substring(binaryString.length() - 8);
}
return res;
}
//二进制字符串转16进制
String a = "11011";
String b = Integer.toHexString(Integer.parseInt(a, 2));
System.out.println("二进制"+a+",转换为十六进制为:"+b);
1.2、多字的存储和解析
在我们使用计算机时,往往不可能单纯使用1个字节进行数据的传输,往往会使用多个字节进行传输和存储,因此,此时便涉及到另两个数据存储名词——大端存储和小端存储
基础概念
大端是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,地址由小向大增加,而数据从高位往低位放;
小端是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。
假设有一个整型数0x12345678,从图中可以看出明显的区别:
因此,我们在处理数据时也要考虑这个问题,一般来说,大端存储的数据是符合我们读取和解析的习惯的,但对于小端存储的数据,我们就需要做对应的处理。
处理方法
在Java中,我们常常使用截取并倒置单个字的形式来处理小端数据,具体数据处理代码如下,以下是四个字节代码的处理方式,我们可以根据字段长度进行对应拓展。
/**
* 该方法将高低位进行转换
* 许转换的高于2字节,char,unsignChar ,int等
* @param hex : 需要反转的数据
* @return
*/
public static String parseHexString(String hex) {
String res = "";
if (hex.length() % 2 != 0) {
throw new RuntimeException("数据长度错误!");
}
switch (hex.length()) {
case 4 :
res = hex.substring(2, 4) + hex.substring(0, 2);
break;
case 6 :
res = hex.substring(4, 6) + hex.substring(2, 4) + hex.substring(0, 2);
break;
case 8 :
res = hex.substring(6, 8) + hex.substring(4, 6) + hex.substring(2, 4) + hex.substring(0, 2);
break;
case 16 :
res = hex.substring(14, 16) + hex.substring(12, 14) + hex.substring(10, 12) + hex.substring(8, 10) +
hex.substring(6, 8) + hex.substring(4, 6) + hex.substring(2, 4) + hex.substring(0, 2);
}
return res;
}
2、ASCII码,ANSI码和16进制字符串的转化
2.1 基础定义
ASCII码
-
American Standard Code for Information Interchange, 叫做“美国信息交换标准码”。
-
一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间
ANSI码
ANSI编码是一种对ASCII码的拓展 ANSI编码用0x00–0x7f (即十进制下的0到127)范围的1 个字节来表示 1 个英文字符 超出一个字节的 0x80~0xFFFF 范围来表示其他语言的其他字符
2.2、相关转化方法和测试
//ASCII转str
public static String strToAscii(String str) {
StringBuilder builder = new StringBuilder();
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
builder.append((int)chars[i]);
}
return builder.toString();
}
//IntStr转ASCII
public static String asciiToIntStr(String asc) {
char[] chars = asc.toCharArray();
StringBuilder r = new StringBuilder();
for (char aChar : chars) {
r.append(Integer.toHexString((int) aChar));
}
return r.toString();
}
//测试程序
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
System.out.println("请输入数据~~");
String msg = scanner.nextLine();
String b = ParseUtils.asciiToIntStr(msg);
System.out.println(b);
System.out.println("你输入的是:"+msg);
}
3、java处理负数
16进制的负数一般是以FF做开头的,我们在处理数据的时候也会用到不同的方法,常见的包括补齐数位,然后进行相应转化:
/**
* 16进制求十进制真值
*/
public static Integer getComplement(String data) {
if (data == null || "".equals(data)) {
return null;
}
StringBuilder sb = new StringBuilder();
int i =0;
while (i < data.length()) {
i++;
sb.append("F");
}
String binaryString = Integer.toBinaryString(Integer.valueOf(data,16));
while (binaryString.length()<16){
binaryString="0"+binaryString;
}
if (binaryString.toUpperCase().startsWith("1")) {
// 默认补码代表负数
return - (Integer.valueOf(sb.toString(), 16) - Integer.valueOf(data, 16) + 1);
} else {
return Integer.valueOf(data, 16);
}
}