1. 密碼學基本概念
密碼學習其實就是將明文進行加密的過程,在這個過程中需要防止別人篡改,攔截解密等。古代也有密碼學的概念,下面主要將解現代密碼學;
2.現代密碼學
① 散列函數
散列函數,也見雜湊函數、摘要函數或哈希函數,可將任意長度的消息經過運算,變成固定長度數值,常見的有MD5
、SHA-1
、SHA256
,多應用在文件校驗,數字簽名中。
- MD5 可以將任意長度的原文生成一個128位(16字節)的哈希值
- SHA-1可以將任意長度的原文生成一個160位(20字節)的哈希值
② 對稱密碼
對稱密碼應用了相同的加密密鑰和解密密鑰。對稱密碼分爲:序列密碼(流密碼),分組密碼(塊密碼)兩種。流密碼是對信息流中的每一個元素(一個字母或一個比特)作爲基本的處理單元進行加密,塊密碼是先對信息流分塊,再對每一塊分別加密。
例如原文爲1234567890,流加密即先對1進行加密,再對2進行加密,再對3進行加密……最後拼接成密文;塊加密先分成不同的塊,如1234成塊,5678成塊,90XX(XX爲補位數字)成塊,再分別對不同塊進行加密,最後拼接成密文。前文提到的古典密碼學加密方法,都屬於流加密。
③ 非對稱密碼
對稱密碼的密鑰安全極其重要,加密者和解密者需要提前協商密鑰,並各自確保密鑰的安全性,一但密鑰泄露,即使算法是安全的也無法保障原文信息的私密性。在實際的使用中,遠程的提前協商密鑰不容易實現,即使協商好,在遠程傳輸過程中也容易被他人獲取,因此非對稱密鑰此時就凸顯出了優勢。
非對稱密碼有兩支密鑰,公鑰(publickey)和私鑰(privatekey),加密和解密運算使用的密鑰不同。用公鑰對原文進行加密後,需要由私鑰進行解密;用私鑰對原文進行加密後(此時一般稱爲簽名),需要由公鑰進行解密(此時一般稱爲驗籤)。公鑰可以公開的,大家使用公鑰對信息進行加密,再發送給私鑰的持有者,私鑰持有者使用私鑰對信息進行解密,獲得信息原文。因爲私鑰只有單一人持有,因此不用擔心被他人解密獲取信息原文。
2 ASCII編碼
ASCII(American Standard Code for Information Interchange,美國信息交換標準代碼)是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。它是現今最通用的單字節編碼系統,並等同於國際標準ISO/IEC 646。
.
字符轉換成ascii碼
public class AsciiDemo { public static void main(String[] args) { char a = 'A'; int b = a; // 打印ascii碼 System.out.println(b); } }
運行程序
注意:這個列子主要用來描述字符轉int的類型時時候根據ascll碼來的。
Byte和bit (字節和位之間的關係)
byte : 字節. 數據存儲的基本單位,比如移動硬盤1T , 單位是byte
bit : 比特, 又叫位. 一個位要麼是0要麼是1. 數據傳輸的單位 , 比如家裏的寬帶100MB,下載速度並沒有達到100MB,一般都是12-13MB,那麼是因爲需要使用 100 / 8
關係: 1Byte = 8bit
注意:byte(字節)是描述數據存儲的單位,而bit(位)是描述數據傳輸的單位。
1.5.1 獲取字符串byte
public class ByteBit { public static void main(String[] args) { String a = "a"; byte[] bytes = a.getBytes(); for (byte b : bytes) { int c=b; // 打印發現byte實際上就是ascii碼 System.out.println(c); } } }
運行程序
1.5.2 byte對應bit
public class ByteBit { public static void main(String[] args) { String a = "a"; byte[] bytes = a.getBytes(); for (byte b : bytes) { int c=b; // 打印發現byte實際上就是ascii碼 System.out.println(c); // 我們在來看看每個byte對應的bit,byte獲取對應的bit String s = Integer.toBinaryString(c); System.out.println(s); } } }
運行程序
打印出來應該是8個bit,但前面是0,沒有打印 ,從打印結果可以看出來,一個英文字符 ,佔一個字節
1.5.3 中文對應的字節 (中文在GBK編碼下, 佔據2個字節 中文在UTF-8編碼下, 佔據3個字節)
// 中文在GBK編碼下, 佔據2個字節 // 中文在UTF-8編碼下, 佔據3個字節 public class ByteBitDemo { public static void main(String[] args) throws Exception{ String a = "尚"; byte[] bytes = a.getBytes(); for (byte b : bytes) { System.out.print(b + " "); String s = Integer.toBinaryString(b); System.out.println(s); } } }
運行程序:我們發現一箇中文是有 3 個字節組成
我們修改 編碼格式 , 編碼格式改成 GBK ,我們在運行發現變成了 2 個字節
public static void main(String[] args) throws Exception{ String a = "尚"; // 在中文情況下,不同的編碼格式,對應不同的字節 //GBK :編碼格式佔2個字節 // UTF-8:編碼格式佔3個字節 byte[] bytes = a.getBytes("GBK"); // byte[] bytes = a.getBytes("UTF-8"); for (byte b : bytes) { System.out.print(b + " "); String s = Integer.toBinaryString(b); System.out.println(s); } }
1.5.4 英文對應的字節 (英文在不同的編碼格式中是一致的,中文在編碼格式是UTF-8的格式中是三個字節)
我們在看看英文,在不同的編碼格式佔用多少字節
public class ByteBit { public static void main(String[] args) throws Exception{ String a = "A"; byte[] bytes = a.getBytes(); // 在中文情況下,不同的編碼格式,對應不同的字節 // byte[] bytes = a.getBytes("GBK"); for (byte b : bytes) { System.out.print(b + " "); String s = Integer.toBinaryString(b); System.out.println(s); } } }
運行程序