English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
前言:ブログを書いてからは久しいですが、最近1年は本当に忙しく、仕事が終わりません。多くのサラリーマンが同じ感じがあると思います。最近NFCの書き込み操作で、チェックビットを計算する必要がありました。一般的には、チェックビットは最初の数バイトの異或演算で得られます。
まずは私が使用しているシーンについて説明します:
一つの16バイトデータはCPUカード(例えば交通カード)に書き込まれ、最後のバイトはチェックコードです---最初の15バイトを異或します。
私はインターネットで他の人が書いたアルゴリズムをいくつか見つけましたが、計算結果が間違っているか、または非常に複雑であったため、自分で一つを作成しました。簡単だと思い、皆さんに共有します。希望して、一緒に交流しましょう。
第一节:異或演算とは何か(主に百度百科から引用、知っている方はスキップしてください)
定義:
異或はexclusiveORと呼ばれ、またはxorと略称されます
異或(xor)は数学演算子です。これは論理演算に適用されます。異或の数学記号は「⊕」、コンピュータ記号は「xor」です。その運算法則は:
a⊕b=(¬a∧b)∨(a∧¬b)
もしa、bの2つの値が異なる場合、異或の結果は1。もしa、bの2つの値が同じであれば、異或の結果は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=xxory
運算規則:
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在英文裡面的定義為eitherone(isone),butnotboth,也即只有一個為真(1)時,取真(1)。
作用:
在計算機中普遍運用,異或(xor)的邏輯符號一般用xor,也有用⊕的:
真⊕假=真
假⊕真=真
假⊕假=假
真⊕真=假
或者為:
True⊕False=True
False⊕True=True
False⊕False=False
True⊕True=False
部分計算機語言用1表示真,用0表示假,所以兩個字節按位異或如下
下面是兩個二進制數值進行異或計算:
現實中用的都是十進制的數值,那麼我們來看一看兩個十進制數值是怎麼進行異或計算:
5⊕2=?
1.進行異或計算前會把數值都轉換為二進制的:
5和2轉為二進制分別為:0101、0010
2.再把结果0111转换为十进制的:7
3.所以5⊕2=7
巧用:
与其它语言不同,C语言和C++语言的异或不用xor,而是用“^”,键入方式为Shift+6。(而其它语言的“^”一般表示乘方)
若需要交换两个变量的值,除了通常使用的借用中间变量进行交换外,还可以利用异或,仅使用两个变量进行交換,如:
a=a^b; b=b^a; a=a^b;
详解:
a1=a^b b=a1^b a=a1^b=a1^(a1^b)=a1^a1^b=b
注意:
a=a^b^(b=a);//この形式は不適切なUB行為であり、異なるコンパイラでは異なる結果が得られます。使用しないでください。
これでaとbの交換が完了しました。
以上のことから、同一の変数と他の変数およびそのXOR値のXORは自身に等しいことになります。
例:暗号化アルゴリズムの一部または複数の段階で使用することができます。これにより、アルゴリズムがより複雑になり、解読しにくくなり、安全性が向上します。[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; } } //XOR演算 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)); }
注意:上記の方法は、16進数文字列の一バイト間のXOR演算に適しています。例えば、15バイトの16進数文字列のXOR演算:
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
つまり、得られる一バイトのチェックサムは以下の通りです:6
補足、一部の友人に簡単な呼び出し方法を追加しました。参考にしてください:
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 は取得した検証コードです。
まとめ
これで、Java プログラミングで十六進文字列の XOR オペレーションを実現するコード例の全てが本文に含まれています。皆様に役立つことを願っています。興味を持たれた方、他の関連トピックもご覧ください。不十分な点があれば、コメントをお待ちしております。皆様のサポートに感謝します。
声明:この記事の内容はインターネットから取得しており、著作権者に帰属します。インターネットユーザーが自発的に貢献し、アップロードしたものであり、このサイトは所有権を持ちません。また、人工的な編集は行われていません。著作権侵害を疑われる内容がある場合は、メールで:notice#wまでお知らせください。3codebox.com(メールを送信する際、#を@に置き換えてください。申し訳ありませんが、関連する証拠を提供していただき、一旦確認がついたら、このサイトは即座に侵害を疑われるコンテンツを削除します。)