Java異或技操作給任意的文件加密原理及使用詳解
異或簡單介紹:異或是一種基于二進制的位運算,用符號XOR或者 ^ 表示,其運算法則是對運算符兩側(cè)數(shù)的每一個二進制位,同值取0,異值取1。
簡單理解就是不進位加法,如1+1=0,,0+0=0,1+0=1。
需求描述
在信息化時代對數(shù)據(jù)進行加密是一個很重要的主題,在做項目的過程中,我也實現(xiàn)了一個比較復雜的加密算法,但是由于涉及到的技術(shù)是保密的,所以在這里我實現(xiàn)一個比較簡單的版本,利用文件的輸入輸出流和異或操作進行任意文件的加密,關(guān)于解密算法,很簡單,自己思考下就能解決。
數(shù)學原理
該加密算法利用的是兩個數(shù)異或的功能,先簡單的說下異或的原理,異或?qū)嶋H上是對文件的二進制編碼進行操作,簡單的說就是當兩個二進制位相同時為0,不同時為1,看下面的例子:
//7的二進制表示: 00000111 //2的二進制表示: 00000010 //兩者異或得到的結(jié)果: 00000101 //也就是數(shù)字5 //--------------------------- //得到的結(jié)果再次和2異或 //5的二進制表示: 00000101 //2的二進制表示: 00000010 //兩者異或得到的結(jié)果: 00000111 //也就是7,是不是很神奇的又回到了7呢?
代碼實現(xiàn)
import java.io.*; class FileSecret { public static void main(String[] args) throws Exception { //找到要加密的文件,盤符自己指定,輸入輸出不需要在同一個盤符 File inFile = new File("盤符:\\加密的文件"); //將要加密的文件輸出到指定的盤符 File outFile = new File("盤符:\\解密的文件"); //建立數(shù)據(jù)通道,讓圖片的二進制數(shù)據(jù)流入 FileInputStream input = new FileInputStream(inFile); FileOutputStream output = new FileOutputStream(outFile); //在讀的過程中,將讀到的數(shù)據(jù)異或一個數(shù)字,這個數(shù)字應(yīng)該是由某種加密算法生成的,在這里我僅僅簡單的編一個數(shù)字928(我的生日),然后進行異或,將得到的數(shù)據(jù)輸出 int content = 0 ; //該變量用于存儲讀取到的數(shù)據(jù),當然這里可以使用long等更長的數(shù)據(jù)類型,當然我們也可以使用其他的數(shù)據(jù)類型,只需要滿足^兩端的數(shù)據(jù)類型能夠相互轉(zhuǎn)換就行,至少能進行強制類型轉(zhuǎn)換 while((content=input.read())!=-1) // 如果沒有到文件的末尾,那么繼續(xù)讀取數(shù)據(jù),讀取到的數(shù)據(jù)已經(jīng)存儲到content變量中了,-1為文件的結(jié)束符 { output.write(content^928); //寫到輸出文件流中 } //關(guān)閉資源 input.close(); output.close(); } }
代碼功能評價
對于這段代碼,功能大體上已經(jīng)能夠用滿足需求,但是存在不足,第一沒有使用加密算法生成異或的另一端數(shù)字,第二我沒有去實現(xiàn)文件的解密,實際上解密十分簡單,請自己仔細讀數(shù)學原理部分就能知道怎么去寫解密算法,實際上加密和解密也不是同一個地方同時實現(xiàn)的,而是加密雙采用相同的加密算法進行運算得出的。
使用隨機數(shù)改進算法
在上面的過程中,我們實際上采用的是給定的一個值去和我們讀入的二進制文件進行異或,那么我們是否能用一個隨機數(shù)去代替這種約定呢?答案是可以的,首先我們采用的是int類型的變量去存儲,那么能表示的范圍是:正負21億的可表示數(shù)字,具體的代碼如下:
//產(chǎn)生隨機數(shù)的方法 import java.util.*; public class RandomTest{ public static void main(String[] args){ Random random = new Random(); int num = random.nextInt(11);//表示產(chǎn)生0-10之間的隨機數(shù),產(chǎn)生的這個隨機數(shù)我們應(yīng)該可以保存,供加密和解密者使用 System.out.println("隨機數(shù)為:"+num); } }
改進后的加密算法
加密端代碼:
import java.io.*; import java.util.*; class FileSecret { public static void main(String[] args) throws Exception { //找到要加密的文件,盤符自己指定,輸入輸出不需要在同一個盤符 File inFile = new File("盤符:\\加密的文件"); //將要加密的文件輸出到指定的盤符 File outFile = new File("盤符:\\解密的文件"); //建立數(shù)據(jù)通道,讓圖片的二進制數(shù)據(jù)流入 FileInputStream input = new FileInputStream(inFile); FileOutputStream output = new FileOutputStream(outFile); //產(chǎn)生加密異或的另一個數(shù)字 Random random = new Random(); int num = random.nextint(11); //表示產(chǎn)生0-10之間的隨機數(shù),產(chǎn)生的這個隨機數(shù)我們應(yīng)該可以保存,供加密和解密者使用 System.out.println("隨機數(shù)為:"+num); //在讀的過程中,將讀到的數(shù)據(jù)異或一個數(shù)字,這個數(shù)字應(yīng)該是由某種加密算法生成的,在這里我僅僅簡單的編一個數(shù)字928(我的生日),然后進行異或,將得到的數(shù)據(jù)輸出 int content = 0 ; //該變量用于存儲讀取到的數(shù)據(jù),當然這里可以使用long等更長的數(shù)據(jù)類型,當然我們也可以使用其他的數(shù)據(jù)類型,只需要滿足^兩端的數(shù)據(jù)類型能夠相互轉(zhuǎn)換就行,至少能進行強制類型轉(zhuǎn)換 while((content=input.read())!=-1) // 如果沒有到文件的末尾,那么繼續(xù)讀取數(shù)據(jù),讀取到的數(shù)據(jù)已經(jīng)存儲到content變量中了,-1為文件的結(jié)束符 { output.write(content^num); //寫到輸出文件流中 } //關(guān)閉資源 input.close(); output.close(); } }
加密端需要將上面代碼中生成的num告知給解密端,否則不能實現(xiàn)文件的解密。
解密端代碼:
import java.io.*; class FileSecret { public static void main(String[] args) throws Exception { //找到要加密的文件,盤符自己指定,輸入輸出不需要在同一個盤符 File inFile = new File("盤符:\\加密的文件"); //將要加密的文件輸出到指定的盤符 File outFile = new File("盤符:\\解密的文件"); //建立數(shù)據(jù)通道,讓圖片的二進制數(shù)據(jù)流入 FileInputStream input = new FileInputStream(inFile); FileOutputStream output = new FileOutputStream(outFile); //在讀的過程中,將讀到的數(shù)據(jù)異或一個數(shù)字,這個數(shù)字應(yīng)該是由某種加密算法生成的,在這里我僅僅簡單的編一個數(shù)字928(我的生日),然后進行異或,將得到的數(shù)據(jù)輸出 int content = 0 ; //該變量用于存儲讀取到的數(shù)據(jù),當然這里可以使用long等更長的數(shù)據(jù)類型,當然我們也可以使用其他的數(shù)據(jù)類型,只需要滿足^兩端的數(shù)據(jù)類型能夠相互轉(zhuǎn)換就行,至少能進行強制類型轉(zhuǎn)換 while((content=input.read())!=-1) // 如果沒有到文件的末尾,那么繼續(xù)讀取數(shù)據(jù),讀取到的數(shù)據(jù)已經(jīng)存儲到content變量中了,-1為文件的結(jié)束符 { output.write(content^從加密端傳來的加密數(shù)字); //寫到輸出文件流中 } //關(guān)閉資源 input.close(); output.close(); } }
再一次改進
其實在我們的代碼中,標準的加密碼應(yīng)該是隨機生成,并且包含有字母、數(shù)字等各種符號,那么我們怎么生成這樣的加密串呢?生成這樣的加密串之后是怎樣將其轉(zhuǎn)化為二進制代碼的?提供一種思路:采用Java的正則表達式可以生成任意你想要的串,然后用字符串轉(zhuǎn)化方法生成相應(yīng)的二進制代碼。我自己實現(xiàn)了一個極其復雜的加密生成方法,但是不能公開,這涉及到實驗室項目的資料,并且有很多的密碼學領(lǐng)域有很多經(jīng)典的加密算法也是可以利用的。
總結(jié)
以上就是本文關(guān)于Java異或技操作給任意的文件加密原理及使用詳解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:
Java使用異或運算實現(xiàn)簡單的加密解密算法實例代碼
Java編程實現(xiàn)對十六進制字符串異或運算代碼示例
如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
相關(guān)文章
使用Java進行Json數(shù)據(jù)的解析(對象數(shù)組的相互嵌套)
下面小編就為大家?guī)硪黄褂肑ava進行Json數(shù)據(jù)的解析(對象數(shù)組的相互嵌套)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08解決SpringCloud下spring-boot-maven-plugin插件的打包問題
這篇文章主要介紹了SpringCloud下spring-boot-maven-plugin插件的打包問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03Mybatis?Interceptor線程安全引發(fā)的bug問題
這篇文章主要介紹了Mybatis?Interceptor線程安全引發(fā)的bug問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02java線程之使用Runnable接口創(chuàng)建線程的方法
本篇文章介紹了,java中使用Runnable接口創(chuàng)建線程的方法。需要的朋友參考下2013-05-05如何解決getReader() has already been called&
這篇文章主要介紹了如何解決getReader() has already been called for this request問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05