[转载] 用Java语言实现对十六进制字符串异或运算

参考链接: 交换两个字符串,而无需在Java中使用第三个用户定义的变量

前言:好久没有写博客,最近一年感觉真是好忙,各种做不完的工作。相信很多上班族都会有这种感觉。最近对NFC进行写卡操作,需要计算一个校验位。一般情况下,校验位多数是由前几个字节进行异或运算所得。 

  

现在我就先说一下我使用的场景: 

把一个16字节的数据写到CPU卡(如交通卡)里面,最后一字节是校验码---前十五字节异或。 

我开始从网上找了一些别人写的算法发现计算后结果不对,或者就是写的太复杂了,于是自己就写了一个,感觉也比较简单,现在分享给大家,希望一起交流一下。 

第一节:什么是异或运算(主要摘自百度百科,熟悉的童靴可以跳过) 

定义: 

 

 

 异或,英文为exclusive OR,或缩写成xor

 

 

 异或(xor)是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为:

 

 

 a⊕b = (¬a ∧ b) ∨ (a ∧¬b)

 

 

 如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

 

 

 异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。

 

 

 异或略称为XOR、EOR、EX-OR

 

 

 程序中有三种演算子:XOR、xor、⊕。

 

 

 使用方法如下

 

 

 z = x ⊕ y

 

 

 z = x xor y

 

运算规则: 

 

 

 

 1. a ⊕ a = 0

 

 

 2. a ⊕ b = b ⊕ a

 

 

 3. a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;

 

 

 4. d = a ⊕ b ⊕ c 可以推出 a = d ⊕ b ⊕ c.

 

 

 5. a ⊕ b ⊕ a = b.

 

 

 6.若x是二进制数0101,y是二进制数1011

 

 

 则x⊕y=1110

 

 

 只有在两个比较的位不同时其结果是1,否则结果为0

 

 

 即“两个输入相同时为0,不同则为1”!

 

 

  

 

逻辑: 

 

 

 

 逻辑表达式:F=AB’⊕A’B((AB’⊕A’B)’=AB⊙A’B’,⊙为“同或”运算)

 

 

 异或逻辑的真值表如图1所

 

 

  示,其逻辑符号如图2所示。异或逻辑的关系是:当AB不同时,输出P=1;当AB相同时,输出P=0。“⊕”是异或运算符号,异或逻辑也是与或非逻辑的组合,其逻辑表达式为:

 

 

 P=A⊕B

 

 

 由图1可知,异或运算的规则是

 

 

 0⊕0=0,0⊕1=1

 

 

 1⊕0=1,1⊕1=0

 

 

 口诀:相同取0,相异取1

  

 

 

 事实上,XOR 在英文里面的定义为either one (is one), but not both, 也即只有一个为真(1)时,取真(1)。

 

作用: 

 

 

 

 在计算机中普遍运用,异或(xor)的逻辑符号一般用xor,也有用⊕的:

 

 

 真⊕假=真

 

 

 假⊕真=真

 

 

 假⊕假=假

 

 

 真⊕真=假

 

 

 或者为:

 

 

 True ⊕ False = True

 

 

 False ⊕ True = True

 

 

 False ⊕ False = False

 

 

 True ⊕ True = False

 

 

 部分计算机语言用1表示真,用0表示假,所以两个字节按位异或如下

 

   

    

     00000000

      

    

     xor

      

    

     00000000

      

    

     ----------------------------------

        

    

     00000000

      

 

 ============我是分界线1============

 

 

 下面是两个二进制数值进行异或计算:

 

   

    

     11111111

      

    

     xor

      

    

     00000000

      

    

     ----------------------------

        

    

     11111111

      

 

 ============我是分界线2============

 

 

 现实中用的都是十进制的数值,那么我们来看一看两个十进制数值是怎么进行异或计算:

 

 

 5 ⊕ 2 = ?

 

 

 1.进行异或计算前会把数值都转换为二进制的:

 

 

 5和2转为二进制分别为:0101 、0010

 

   

    

     0101

      

    

     xor

      

    

     0010

      

    

     ----------------------------

        

    

     0111

      

 

 2.再把结果 0111 转换为十进制的:7

 

 

 3.所以 5 ⊕ 2 = 7

 

巧用: 

 

 

 

 与其它语言不同,C语言和C++语言的异或不用xor,而是用“^”,键入方式为Shift+6。(而其它语言的“^”一般表示乘方)

 

 

 若需要交换两个变量的值,除了通常使用的借用中间变量进行交换外,还可以利用异或,仅使用两个变量进行交换,如:

 

 

  

   

       

       1

       

       

       2

       

       

       3

        

       

        

        a=a^b;

        

        

        b=b^a;

        

        

        a=a^b;

        

        

  

 

 

 详解:

 

 

  

   

       

       1

       

       

       2

       

       

       3

        

       

        

        a1=a^b

        

        

        b=a1^b

        

        

        a=a1^b=a1^(a1^b)=a1^a1^b=b

        

        

  

 

 

 注意:

 

 

  

   

       

       1

        

       

        

        a=a^b^(b=a);//此类形式是不正确的UB行为,在不同编译器中会有不同的结果,切勿使用

        

        

  

 

 

 这样就完成了a与b的交换。

 

 

 综上:同一变量与另一变量和其异或值异或等于自身。

 

 

 用例:可使用于加密算法某一环节或更多环节,使算法更复杂,不易被破解,安全性更高。[1] 

 

第二节:用java语言实现: 

 

  

 

private static String xor(String strHex_X,String strHex_Y){ 

            //将x、y转成二进制形式 

            String anotherBinary=Integer.toBinaryString(Integer.valueOf(strHex_X,16)); 

            String thisBinary=Integer.toBinaryString(Integer.valueOf(strHex_Y,16)); 

            String result = ""; 

            //判断是否为8位二进制,否则左补零 

            if(anotherBinary.length() != 8){ 

            for (int i = anotherBinary.length(); i <8; i++) { 

                    anotherBinary = "0"+anotherBinary; 

                } 

            } 

            if(thisBinary.length() != 8){ 

            for (int i = thisBinary.length(); i <8; i++) { 

                    thisBinary = "0"+thisBinary; 

                } 

            } 

            //异或运算 

            for(int i=0;i<anotherBinary.length();i++){ 

            //如果相同位置数相同,则补0,否则补1 

                    if(thisBinary.charAt(i)==anotherBinary.charAt(i)) 

                        result+="0"; 

                    else{ 

                        result+="1"; 

                    } 

                }

            Log.e("code",result);

            return Integer.toHexString(Integer.parseInt(result, 2)); 

        } 

注意:以上方法是针对一个十六进制字符串一字节之间的异或运算,如对十五字节的十六进制字符串异或运算:1312f70f900168d900007df57b4884 

先进行拆分:13 12 f7 0f 90 01 68 d9 00 00 7d f5 7b 48 84 

13 xor 12-->1 

1 xor f7-->f6 

f6 xor 0f-->f9 

.... 

62 xor 84-->e6 

即,得到的一字节校验码为:e6 

补充,给一些朋友增加了一个简单的调用方法,仅供参考: 

 

public String checkcode_0007(String para){

         String[] dateArr = new String[15];

         try {

             dateArr[0] = para.substring(0, 2);

             dateArr[1] = para.substring(2, 4);

             dateArr[2] = para.substring(4, 6);

             dateArr[3] = para.substring(6, 8);

             dateArr[4] = para.substring(8, 10);

             dateArr[5] = para.substring(10, 12);

             dateArr[6] = para.substring(12, 14);

             dateArr[7] = para.substring(14, 16);

             dateArr[8] = para.substring(16, 18);

             dateArr[9] = para.substring(18, 20);

             dateArr[10] = para.substring(20, 22);

             dateArr[11] = para.substring(22, 24);

             dateArr[12] = para.substring(24, 26);

             dateArr[13] = para.substring(26, 28);

             dateArr[14] = para.substring(28, 30);

        } catch (Exception e) {

            // TODO: handle exception

        }

        String code = "";

        for (int i = 0; i < dateArr.length-1; i++) {

            if(i == 0){

                code = xorString(dateArr[i], dateArr[i+1]);

            }else{

                code = xorString(code, dateArr[i]);

            }

        }

        return code;

}然后再主函数或者其他方法里面调用: 

 

 

String code = checkcode_0007("1312f70f900168d900007df57b4884");code就是获取的校验码了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL日常应用操作记录

1.知道一个字段名&#xff0c;怎样查到它在数据库里的哪张表里&#xff1f; USE Information_schema;SELECT TABLE_NAME FROM COLUMNS WHERE COLUMN_NAME字段名称; MySQL中查看库表字段信息都在information_schemal中&#xff0c;获取数据字典等信息都要通过这个视图。 如&…

[转载] 【Java】将一个字符串的字符排序,按ASCII表的顺序从小到大

参考链接&#xff1a; 在Java中搜索字符串中的字符和子字符串 将一个字符串的字符按ASCII表的顺序从小到大排序&#xff0c;如将字符串“asdafxcvMADb”排序为“ADMaabcdfsvx” 算法的基本思想&#xff1a; 先将字符串转化为一个char类型的数组&#xff0c;来进行存储&#xf…

如果只做前端验证的话,谈jjdd.com的看照片功能。

如果你在上海&#xff0c;并且坐过地铁的话&#xff0c;你肯定知道jjdd.com。 这个网站和百合&#xff0c;世纪佳缘类似&#xff0c;都是交朋友的性质。 在jjdd.com中有个很重要的功能&#xff1a;如果你上传的照片比你想看的人少的话&#xff0c;你是不能看她的照片的。 例如如…

[转载] 快速学习-Mybatis框架概述

参考链接&#xff1a; Java在竞争性编程中的快速I/O 第1章 框架概述 1.1 什么是框架 1.1.1 什么是框架 框架&#xff08;Framework&#xff09;是整个或部分系统的可重用设计&#xff0c;表现为一组抽象构件及构件实例间交互的方法;另一种定义认为&#xff0c;框架是可被…

3、MySQL的数据类型介绍

上一章节内容主要介绍了一些MySQL中对表和库的增删改查操作&#xff0c;对于上一章中对与表中字段的一些定义进行说明&#xff0c;本章主要介绍关于数据库类型的一些定义。一、概述&#xff1a;MySQL数据库中的数据大致可以分为以下几类&#xff0c;从而实现数据库在操作的时候…

[转载] 必须要会回答的Java面试题(字符串篇)

参考链接&#xff1a; 比较Java中的两个字符串String 最近很多学习java的小白问我字串相关的问题&#xff0c;觉得很有必要整理下&#xff0c;以方便初学者理解字符串以及应对今后面试中考官的提问。 如果你是有几年Java开发经验&#xff0c;可以根据目录选择性的阅读以下内…

[转载] java如何实现一个字符串的反转和替换

参考链接&#xff1a; 反转Java中的字符串String 一、java字符串的反转 1.利用java字符串的拼接实现字符串的反转&#xff0c;代码如下&#xff1a; public static String reverse(String s){ int lens.length(); String str""; for (int i 0; i < len; i) { …

java 中的instanceof

java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出&#xff0c;这个对象是否是这个特定类或者是它的子类的一个实例。 用法&#xff1a;result object instanceof class参数&#xff1a;Result&#xff1a;布尔类…

[转载] 将一个整数型字符串转换为一个整数

参考链接&#xff1a; Java中整数到字符串转换的不同方法 package com.utl.string; /* * 将一组整数字符串转换为整数 * 例&#xff1a;"234"转换为整数型234 * 分析&#xff1a;涉及到许多问题&#xff0c;例如非法输入&#xff0c;有正负号&#xff0c;是否为空字…

升级PowerShell至4.0版本

为了更好的使用Cmder v1.2&#xff0c;不得不升级PowerShell为4.0。 不知道Cmder的&#xff0c;可以点击这里&#xff1a;https://github.com/cmderdev/cmder 和 逆天神器 cmder。 Powershell是运行在Windows机器上实现系统和应用程序管理自动化的命令行脚本环境。 需要.NET环境…

[转载] 字符串太长 pep8_Python f字符串– PEP 498 –文字字符串插值

参考链接&#xff1a; 从Java中的字符串中删除前导零 字符串太长 pep8 Python f-strings or formatted strings are the new way to format strings. This feature was introduced in Python 3.6 under PEP-498. It’s also called literal string interpolation. Python f字符…

备忘(持续更新。。。)

1、在springmvc这个框架里面&#xff0c;创建新的业务逻辑层&#xff0c;dao、service层至少需要一个接口&#xff0c;项目才能跑起来 2、获取当前用户桌面路径 File desktopDir FileSystemView.getFileSystemView() .getHomeDirectory();String desktopPath desktopDir.getA…

[转载] 字符串操作截取后面的字符串_对字符串的5个必知的熊猫操作

参考链接&#xff1a; 修剪Java中的字符串(删除前导和尾随空格) 字符串操作截取后面的字符串 We have to represent every bit of data in numerical values to be processed and analyzed by machine learning and deep learning models. However, strings do not usually co…

更改域控制器的计算机名

林功能级别必须为Windows Server 2003及以上 1. netdom computername Server08-1.contoso.com /add:08Server1.contoso.com 2. netdom computername Server08-1.contoso.com /makeprimary:08Server1.contoso.com 3. Restart your computer 4. netdom computername 08Server1.co…

[转载] Google Java代码规范

参考链接&#xff1a; 使用Java计算文本文件txt中的行数/单词数/字符数和段落数 原文地址&#xff1a;https://google.github.io/styleguide/javaguide.html GIthub上GoogleCode风格的配置文件&#xff08;支持Eclipse IDE和IntelliJ IDE&#xff09;&#xff1a;https://git…

SQL PASS西雅图之行——签证篇

本人有幸通过IT168&itpub的站庆活动http://www.itpub.net/thread-1716961-1-1.html&#xff0c;并应微软邀请参加了在西雅图举办的The Conference for SQL Server Professionals&#xff08;简称SQL-PASS&#xff09;。 SQL-PASS会议计划于2012年11月6日-9日举行&#xff0…

[转载] java8 lambda表达式 List转为Map

参考链接&#xff1a; 使用Lambda表达式检查字符串在Java中是否仅包含字母 public static void main(String[] args) { List<User> userList new ArrayList<User>(); User user0 new User("han1", "男1", 20); User user1 new User("…

11.python并发入门(part5 event对象)

一、引入event。 每个线程&#xff0c;都是一个独立运行的个体&#xff0c;并且每个线程的运行状态是无法预测的。 如果一个程序中有很多个线程&#xff0c;程序的其他线程需要判断某个线程的运行状态&#xff0c;来确定自己下一步要执行哪些操作。 threading模块中的event对象…

[转载] Java 将字符串首字母转为大写 - 利用ASCII码偏移

参考链接&#xff1a; 使用ASCII值检查Java中的字符串是否仅包含字母 将字符串name 转化为首字母大写。普遍的做法是用subString()取第一个字母转成大写再与之后的拼接&#xff1a; str str.substring(0, 1).toUpperCase() str.substring(1); 看到一种效率更高的做法&…

俞永福卸任阿里大文娱董事长,改任 eWTP 投资组长

两天前&#xff08;11月13日&#xff09;&#xff0c;阿里文娱董事长俞永福离职的消息&#xff0c;在互联网圈炸了锅。但很快&#xff0c;俞本人就在微博做了澄清&#xff0c;并称“永远幸福&#xff0c;我不会离开”。然而就在今天&#xff08;11月15日&#xff09;&#xff0…