详解Java异或运算符
异或是⼀种基于⼆进制的位运算,⽤符号XOR或者^表⽰,其运算法则是对运算符两侧数的每⼀个⼆进制位同值则取0,异值则取1.
简单理解就是不进位加法,如1+1=0,0+0=0,1+0=1.
For example: 3^5 = 6
转成⼆进制后就是 0011 ^ 0101 ⼆号位和三号位都是异值取1 末尾两个1同值取零,所以3^5 = 0110 = 6
前言
异或运算主要用于判断两个值是否一样
异或运算的3个性质:
1.任何数和0进行异或运算,结果是原来的数,即b⊕0=b
2.任何数和其自身进行异或运算,结果为0,即b⊕b=0。
3.异或运算满足交换律和结合律,即x⊕y⊕x=y⊕(x⊕x)=y
一、异或工具类
代码如下(示例):
package com.bly.demo;
import java.math.BigInteger;
/**
* @ClassName BaseConversionUtils
* @Author zhao
* @Date 9:53 2022/05/30
* @Description 进制转换类和校验和互相异或 计算
* @Version 1.0
**/
public class BaseConversionUtils {
/**
* 校验和 互相异或 计算 传字符串 例如:“8A010133” 结果:b9
*/
public static String getCheckXOR(String s) {
String regex = "(.{2})";
String replace = s.replaceAll(regex, "$1 ");
String[] st = replace.split(" ");
int[] c = new int[st.length + 1];
for (int i = 0; i < st.length; i++) {
int i1 = Integer.parseInt(st[i], 16);
c[i] = i1;
}
char x = 0;
for (int i = 0; i < c.length; i++) {
x ^= c[i];
}
return String.format("%x", (int) x);
}
/**
* 十进制转换指定进制大小进制(11- 20 进制内 闭区间)
*
* @param original
* 十进制显示的数字字符串 (最大支持long的最大)
* @param baseType
* 转换后对的进制类型
* @return
*/
public static String encrypt(String original, BaseType baseType) {
if (baseType == null) {
throw new RuntimeException("进制转换类型不能为null");
}
Long length = baseType.getBaseLength();
long value = Long.valueOf(original).longValue();
StringBuilder builder = new StringBuilder();
int i = 0;
while (value != 0) {
long t = value % length;
if (t >= 0 && t < 10) {
builder.append((char) (t + '0'));
} else {
builder.append((char) (t + 'A' - 10));
}
i++;
value = value / length;
}
String num = builder.reverse().toString();
while (num.startsWith("0")) {
num = num.substring(1, num.length());
}
return num;
}
/**
* 十进制转换指定进制大小进制(11- 20 进制内 闭区间)
*
* @param original
* 十进制显示的数字字符串
* @param baseType
* 转换后对的进制类型
* @return
*/
public static String encryptByBigInt(String original, BaseType baseType) {
if (baseType == null) {
throw new RuntimeException("进制转换类型不能为null");
}
BigInteger length = BigInteger.valueOf(baseType.getBaseLength());
BigInteger value = new BigInteger(original);
StringBuilder builder = new StringBuilder();
int i = 0;
while (!value.toString().equals("0")) {
int t = value.mod(length).intValue();
if (t >= 0 && t < 10) {
builder.append((char) (t + '0'));
} else {
builder.append((char) (t + 'A' - 10));
}
i++;
value = value.divide(length);
}
String num = builder.reverse().toString();
while (num.startsWith("0")) {
num = num.substring(1, num.length());
}
return num;
}
/**
* 十进制转换指定进制大小进制(11- 35 进制内 闭区间) 十进制字符串包括以0开头的编译(转换值在long范围类)
*
* @param original
* 十进制显示的数字字符串
* @param baseType
* 转换后对的进制类型
* @return
*/
public static String encryptToStartZero(String original, BaseType baseType) {
if (baseType == null) {
throw new RuntimeException("进制转换类型不能为null");
}
Long length = baseType.getBaseLength();
int a = 0;
while (original.startsWith("0")) {
original = original.substring(1, original.length());
a++;
}
long value = Long.valueOf(original).longValue();
StringBuilder builder = new StringBuilder();
int i = 0;
while (value != 0) {
long t = value % length;
if (t >= 0 && t < 10) {
builder.append((char) (t + '0'));
} else {
builder.append((char) (t + 'A' - 10));
}
i++;
value = value / length;
}
String num = builder.reverse().toString();
while (num.startsWith("0")) {
num = num.substring(1, num.length());
}
if (a == 0) {
num = "1" + num;
} else {
num = "0" + a + num;
}
return num;
}
/**
* 十进制转换指定进制大小进制(11- 35 进制内 闭区间) 十进制字符串包括以0开头的编译
*
* @param original
* 十进制显示的数字字符串
* @param baseType
* 转换后对的进制类型
* @return
*/
public static String encryptToStartZeroToBigInt(String original, BaseType baseType) {
if (baseType == null) {
throw new RuntimeException("进制转换类型不能为null");
}
BigInteger length = BigInteger.valueOf(baseType.getBaseLength());
int a = 0;
while (original.startsWith("0")) {
original = original.substring(1, original.length());
a++;
}
BigInteger value = new BigInteger(original);
StringBuilder builder = new StringBuilder();
int i = 0;
while (!value.toString().equals("0")) {
int t = value.mod(length).intValue();
if (t >= 0 && t < 10) {
builder.append((char) (t + '0'));
} else {
builder.append((char) (t + 'A' - 10));
}
i++;
value = value.divide(length);
}
String num = builder.reverse().toString();
while (num.startsWith("0")) {
num = num.substring(1, num.length());
}
if (a == 0) {
num = "1" + num;
} else {
num = "0" + a + num;
}
return num;
}
/**
* 进制大小进制(11- 35 进制内 闭区间)转换为10进制 (编译前只支持long的最大值 否则结果会不正确)
*
* @param translation
* (11- 35 进制内 闭区间)进制显示的数字字符串
* @param baseType
* 需要转换的进制类型
* @return
*/
public static String decrypt(String translation, BaseType baseType) {
Long length = baseType.getBaseLength();
long result = 0;
long wei = 1;
char[] chars = translation.toCharArray();
for (int i = chars.length - 1; i >= 0; i--) {
int a = 0;
switch (chars[i]) {
case 'A' :
a = 10;
break;
case 'B' :
a = 11;
break;
case 'C' :
a = 12;
break;
case 'D' :
a = 13;
break;
case 'E' :
a = 14;
break;
case 'F' :
a = 15;
break;
case 'G' :
a = 16;
break;
case 'H' :
a = 17;
break;
case 'I' :
a = 18;
break;
case 'J' :
a = 19;
break;
case 'K' :
a = 20;
break;
case 'L' :
a = 21;
break;
case 'M' :
a = 22;
break;
case 'N' :
a = 23;
break;
case 'O' :
a = 24;
break;
case 'P' :
a = 25;
break;
case 'Q' :
a = 26;
break;
case 'R' :
a = 27;
break;
case 'S' :
a = 28;
break;
case 'T' :
a = 29;
break;
case 'U' :
a = 30;
break;
case 'V' :
a = 31;
break;
case 'W' :
a = 32;
break;
case 'X' :
a = 33;
break;
case 'Y' :
a = 34;
break;
case 'Z' :
a = 35;
break;
default :
a = Integer.valueOf(String.valueOf(chars[i]));
break;
}
result += a * wei;
wei *= length;
}
return String.valueOf(result);
}
/**
* 进制大小进制(11- 35 进制内 闭区间)转换为10进制
*
* @param translation
* (11- 35 进制内 闭区间)进制显示的数字字符串
* @param baseType
* 需要转换的进制类型
* @return
*/
public static String decryptByBigInt(String translation, BaseType baseType) {
BigInteger length = BigInteger.valueOf(baseType.getBaseLength());
BigInteger result = new BigInteger("0");
BigInteger wei = new BigInteger("1");
char[] chars = translation.toCharArray();
for (int i = chars.length - 1; i >= 0; i--) {
long a = 0;
switch (chars[i]) {
case 'A' :
a = 10l;
break;
case 'B' :
a = 11l;
break;
case 'C' :
a = 12l;
break;
case 'D' :
a = 13l;
break;
case 'E' :
a = 14l;
break;
case 'F' :
a = 15l;
break;
case 'G' :
a = 16l;
break;
case 'H' :
a = 17l;
break;
case 'I' :
a = 18l;
break;
case 'J' :
a = 19l;
break;
case 'K' :
a = 20l;
break;
case 'L' :
a = 21l;
break;
case 'M' :
a = 22l;
break;
case 'N' :
a = 23l;
break;
case 'O' :
a = 24l;
break;
case 'P' :
a = 25l;
break;
case 'Q' :
a = 26l;
break;
case 'R' :
a = 27l;
break;
case 'S' :
a = 28l;
break;
case 'T' :
a = 29l;
break;
case 'U' :
a = 30l;
break;
case 'V' :
a = 31l;
break;
case 'W' :
a = 32l;
break;
case 'X' :
a = 33l;
break;
case 'Y' :
a = 34l;
break;
case 'Z' :
a = 35l;
break;
default :
a = Long.valueOf(String.valueOf(chars[i]));
break;
}
BigInteger multiply = wei.multiply(BigInteger.valueOf(a));
result = result.add(multiply);
wei = wei.multiply(length);
}
return result.toString();
}
/**
* 进制大小进制(11- 35 进制内 闭区间)转换为10进制 数字字符串有零开头的情况 (编译前只支持long的最大值 否则结果会不正确)
*
* @param translation
* (11- 35 进制内 闭区间)进制显示的数字字符串
* @param baseType
* 需要转换的进制类型
* @return
*/
public static String decryptToStartZero(String translation, BaseType baseType) {
Long length = baseType.getBaseLength();
long result = 0;
long wei = 1;
int a1 = 0;
if (translation.startsWith("0")) {
char c = translation.charAt(1);
a1 = Integer.valueOf(String.valueOf(c));
translation = translation.substring(2, translation.length());
} else {
translation = translation.substring(1, translation.length());
}
char[] chars = translation.toCharArray();
for (int i = chars.length - 1; i >= 0; i--) {
int a = 0;
switch (chars[i]) {
case 'A' :
a = 10;
break;
case 'B' :
a = 11;
break;
case 'C' :
a = 12;
break;
case 'D' :
a = 13;
break;
case 'E' :
a = 14;
break;
case 'F' :
a = 15;
break;
case 'G' :
a = 16;
break;
case 'H' :
a = 17;
break;
case 'I' :
a = 18;
break;
case 'J' :
a = 19;
break;
case 'K' :
a = 20;
break;
case 'L' :
a = 21;
break;
case 'M' :
a = 22;
break;
case 'N' :
a = 23;
break;
case 'O' :
a = 24;
break;
case 'P' :
a = 25;
break;
case 'Q' :
a = 26;
break;
case 'R' :
a = 27;
break;
case 'S' :
a = 28;
break;
case 'T' :
a = 29;
break;
case 'U' :
a = 30;
break;
case 'V' :
a = 31;
break;
case 'W' :
a = 32;
break;
case 'X' :
a = 33;
break;
case 'Y' :
a = 34;
break;
case 'Z' :
a = 35;
break;
default :
a = Integer.valueOf(String.valueOf(chars[i]));
break;
}
result += a * wei;
wei *= length;
}
if (a1 != 0) {
String suffix = "";
for (int i = a1; i > 0; i--) {
suffix += 0;
}
return suffix + String.valueOf(result);
}
return String.valueOf(result);
}
/**
* 进制大小进制(11- 35 进制内 闭区间)转换为10进制 数字字符串有零开头的情况
*
* @param translation
* (11- 35 进制内 闭区间)进制显示的数字字符串
* @param baseType
* 需要转换的进制类型
* @return
*/
public static String decryptToStartZeroByBigInt(String translation, BaseType baseType) {
BigInteger length = BigInteger.valueOf(baseType.getBaseLength());
BigInteger result = BigInteger.valueOf(0l);
BigInteger wei = BigInteger.valueOf(1l);
int a1 = 0;
if (translation.startsWith("0")) {
char c = translation.charAt(1);
a1 = Integer.valueOf(String.valueOf(c));
translation = translation.substring(2, translation.length());
} else {
translation = translation.substring(1, translation.length());
}
char[] chars = translation.toCharArray();
for (int i = chars.length - 1; i >= 0; i--) {
long a = 0;
switch (chars[i]) {
case 'A' :
a = 10l;
break;
case 'B' :
a = 11l;
break;
case 'C' :
a = 12l;
break;
case 'D' :
a = 13l;
break;
case 'E' :
a = 14l;
break;
case 'F' :
a = 15l;
break;
case 'G' :
a = 16l;
break;
case 'H' :
a = 17l;
break;
case 'I' :
a = 18l;
break;
case 'J' :
a = 19l;
break;
case 'K' :
a = 20l;
break;
case 'L' :
a = 21l;
break;
case 'M' :
a = 22l;
break;
case 'N' :
a = 23l;
break;
case 'O' :
a = 24l;
break;
case 'P' :
a = 25l;
break;
case 'Q' :
a = 26l;
break;
case 'R' :
a = 27l;
break;
case 'S' :
a = 28l;
break;
case 'T' :
a = 29l;
break;
case 'U' :
a = 30l;
break;
case 'V' :
a = 31l;
break;
case 'W' :
a = 32l;
break;
case 'X' :
a = 33l;
break;
case 'Y' :
a = 34l;
break;
case 'Z' :
a = 35l;
break;
default :
a = Long.valueOf(String.valueOf(chars[i]));
break;
}
result = result.add(wei.multiply(BigInteger.valueOf(a)));
wei = wei.multiply(length);
}
if (a1 != 0) {
String suffix = "";
for (int i = a1; i > 0; i--) {
suffix += 0;
}
return suffix + result.toString();
}
return String.valueOf(result);
}
/**
* 进制种类枚举
*/
public enum BaseType {
BASE_11(11L), BASE_12(12L), BASE_13(13L), BASE_14(14L), BASE_15(15L), BASE_16(16L), BASE_17(17L), BASE_18(18L), BASE_19(19L), BASE_20(20L), BASE_21(21L), BASE_22(22L), BASE_23(23L), BASE_24(24L), BASE_25(25L), BASE_26(26L), BASE_27(
27L), BASE_28(28L), BASE_29(29L), BASE_30(30L), BASE_31(31L), BASE_32(32L), BASE_33(33L), BASE_34(34L), BASE_35(35L);
private Long BaseLength;
public Long getBaseLength() {
return BaseLength;
}
public void setBaseLength(Long baseLength) {
BaseLength = baseLength;
}
BaseType(Long baseLength) {
this.BaseLength = baseLength;
}
}
}
二、使用步骤
public static void main(String[] args) {
String result = "";
// 我这是开第二十四个个柜子
String num = StringUtils.leftPad(BaseConversionUtils.encrypt("15", BaseConversionUtils.BaseType.BASE_16), 2, '0');
System.out.println(num);
result = "8A01" + num + "33";
// 异或运算的值
String checkXOR = BaseConversionUtils.getCheckXOR(result);
System.out.println(checkXOR);
result += checkXOR;
// 最后发送的命令
System.out.println(result);
}
总结
运算规则:相同取0,相异取1
大家理解一下思想就好了