<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    Java之Caesar與Vigenere實現

    1、背景介紹

      話說目前做所謂“企業”開發的語言基本就集中在運用.Net和J2EE上了。又話說,在下很不幸又和Java“同流合污”了一把。現在回想起來,真是感慨萬千啊~遙想公瑾當年,小喬初嫁了,雄姿英發,羽扇綸巾,談笑間,強虜灰飛煙滅。~

      額,下面插播一下正題。其實,目前國內用Java做真正的“企業級”得其實并不是很多,絕大多數都是用個SSH1就覺得這就是Java之企業級開發了,之后就開始沾沾自喜了。這你說讓Servlet和EJB3情何以堪啊~所以說,目前國內大多數Java的開發環境并不能說真正的武裝到牙齒。

      基于這樣的原因,有些時候,我們在做一些“工程”的時候~,當然對于多數情況就是IDE菜單選擇“新建工程”這么個選項出來的貨了,對于某些應用,需要用到一些加密算法,雖說Java自身帶有專門的加密庫,但是那個用起來的確有些麻煩,而且加密算法還是動態加載的,在本地測試的話問題還不是很大,痛苦的是萬一到服務器上一跑,這個加密算法加載失敗什么的,這可就大條了。如果說是一個什么認證系統之類的,那也就罷了。但如果只是一些對密碼強要求很低,但不加密又不行的情況,那的確是挺麻煩的一件事情。

      那么,處于對易用性,易實現性的考慮,那些什么DES算法就暫時不考慮了。如果真有這個需求的話,相信找個健壯性很高的DES問題還不是很大的。而在那許多經典的加密算法中,要數Caesar加密比較經典了。所以,處于這樣的一個需求,就打算實現一個經典加密算法。

      2、Caesar加密算法

      Caesar加密算法算是經典加密算法中最簡單的了。對于標準的Caesar來說,就是把字母序列向后移動一定的數量,替換后得到密文,而這個數量為固定值3。也就是說,在都是由英文字母組成的文本里,字母A將會被替換成D,B會被替換成E,以此類推。

      對于Caesar加密算法,存在幾點問題。首先是這個作為密鑰的值是個固定的3,而且字母表又是按順序排列的,所以只要對方知道你是用Caesar加密的,就很容易的脫密成原文,雖然有些麻煩,但是這就和用原文是差不多的,即使對加密要求很低也不能低成這樣不是?然后是這個替換表,因為是基于字母表的,所以對于英文來說只能加密英文字母,這樣就不能被支持了。最后,因為替換是固定的,所以,對于同一個字母,加密后的字母也是固定的。比如“AAA”這個文本加密后,就是“DDD”,看起來還不夠迷惑人。

      基于以上的原因,我這里實現的Caesar做了一些修改,但是總的思路還是Caesar。

    1. public class Caesar {  
    2.     private String table;  
    3.     private int seedA = 1103515245;  
    4.     private int seedB = 12345;  
    5.       
    6.     public Caesar(String table, int seed) {  
    7.         this.table = chaos(table, seed, table.length());  
    8.     }  
    9.     public Caesar(String table) {  
    10.         this(table, 11);  
    11.     }  
    12.     public Caesar() {  
    13.         this(11);  
    14.     }  
    15.     public Caesar(int seed) {  
    16.         this("ABCDEFGHIJKLMNOPQRSTUVWXYZ", seed);  
    17.     }  
    18.     public char dict(int i, boolean reverse) {  
    19.         int s = table.length(), index = reverse ? s - i : i;  
    20.         return table.charAt(index);  
    21.     }  
    22.     public int dict(char c,  boolean reverse) {  
    23.         int s = table.length(), index = table.indexOf(c);  
    24.         return reverse ? s - index : index;  
    25.     }  
    26.     public int seed(int seed) {  
    27.         long temp = seed;  
    28.         return (int)((temp * seedA + seedB) & 0x7fffffffL);  
    29.     }  
    30.   
    31.     public String chaos(String data, int seed, int cnt) {  
    32.         StringBuffer buf = new StringBuffer(data);  
    33.         char tmp; int a, b, r = data.length();  
    34.         for (int i = 0; i < cnt; i += 1) {  
    35.             seed = seed(seed); a = seed % r;  
    36.             seed = seed(seed); b = seed % r;  
    37.             tmp = buf.charAt(a);  
    38.             buf.setCharAt(a, buf.charAt(b));  
    39.             buf.setCharAt(b, tmp);  
    40.         }  
    41.         return buf.toString();  
    42.     }  
    43.   
    44.     public String crypto(boolean reverse,  
    45.                          int key, String text) {  
    46.         String ret = null;  
    47.         StringBuilder buf = new StringBuilder();  
    48.         int m, s = table.length(), e = text.length();  
    49.   
    50.         for(int i = 0; i < e; i += 1) {  
    51.             m = dict(text.charAt(i), reverse);  
    52.             if (m < 0break;  
    53.             m = m + key + i;  
    54.             buf.append(dict(m % s, reverse));  
    55.         }  
    56.         if (buf.length() == e)  
    57.             ret = buf.toString();  
    58.         return ret;  
    59.     }  
    60.     public String encode(int key, String text) {  
    61.         return crypto(false, key, text);  
    62.           
    63.     }  
    64.     public String decode(int key, String text) {  
    65.         return crypto(true , key, text);  
    66.     }  
    67.       
    68.     public static void main(String[] args) {  
    69.         Caesar caesar = new Caesar();  
    70.         String data = caesar.encode(32"APPLE");  
    71.         caesar.decode(32, data);  
    72.     }  
    73. }

    在上面的Caesar實現中,我用一個整數替代了原來作為密鑰的固定值3。其次,可以通過傳入不同的字符集讓這個加密算法的適用性更廣泛。最后,算法類在初始化的時候,會對替換表做一次擾亂操作,這樣的話,即使是相同的替換表,因為初始化傳入的seed不同,加密出來的內容也會不同。至于程序的細節,我想源碼會更直觀的告訴你的。

      3、Vigenere加密算法

      其實,Vigenere加密算法從歷史考證來看好像并不是一個叫Vigenere的人發明的。大概只是因為某些機緣巧合,被一個叫Vigenere的人用了,并且流傳開了,然后就被叫做Vigenere加密算法了。后來發現這原來是一個美麗的誤解,但是既然都已經被叫習慣了,改口自然是很難了,因此就那么流傳下來了。說道這里,Bellaso先生又一次的淚目了。

      為什么我這里要把Vigenere密碼和Caesar放在一起呢?因為Vigenere算是一個升級版的Caesar算法。所以,當時實現了那個Caesar后,就順帶連 Bellaso 和 Vigenere 先生,也一起緬懷一下了。和Caesar相比Vigenere是一個多表替代,就是說針對明文中不同位置的字母,會選用不同的替換表來加密。如果用上面的例子來說,對于不同位置的字母,會選擇不同的key去加密。說白了,就是多個Caesar疊加起來就是Vigenere。

      雖然說Vigenere在加密的效果上比Caesar有很多提升了,也彌補了Caesar上存在的一些問題。但是,我的實現還是做了一些小小的調整。

    1. public class Vigenere {  
    2.     private String table;  
    3.     private int seedA = 1103515245;  
    4.     private int seedB = 12345;  
    5.       
    6.     public Vigenere(String table, int seed) {  
    7.         this.table = chaos(table, seed, table.length());  
    8.     }  
    9.     public Vigenere(String table) {  
    10.         this(table, 11);  
    11.     }  
    12.     public Vigenere() {  
    13.         this(11);  
    14.     }  
    15.     public Vigenere(int seed) {  
    16.         this("ABCDEFGHIJKLMNOPQRSTUVWXYZ", seed);  
    17.     }  
    18.       
    19.     private char dict(int i, boolean reverse) {  
    20.         int s = table.length(), index = reverse ? s - i : i;  
    21.         return table.charAt(index);  
    22.     }  
    23.     private int dict(char c,  boolean reverse) {  
    24.         int s = table.length(), index = table.indexOf(c);  
    25.         return reverse ? s - index : index;  
    26.     }  
    27.     private int seed(int seed) {  
    28.         long temp = seed;  
    29.         return (int)((temp * seedA + seedB) & 0x7fffffffL);  
    30.     }  
    31.   
    32.     public String chaos(String data, int seed, int cnt) {  
    33.         StringBuffer buf = new StringBuffer(data);  
    34.         char tmp; int a, b, r = data.length();  
    35.         for (int i = 0; i < cnt; i += 1) {  
    36.             seed = seed(seed); a = seed % r;  
    37.             seed = seed(seed); b = seed % r;  
    38.             tmp = buf.charAt(a);  
    39.             buf.setCharAt(a, buf.charAt(b));  
    40.             buf.setCharAt(b, tmp);  
    41.         }  
    42.         return buf.toString();  
    43.     }  
    44.     public String crypto(boolean reverse,  
    45.                          String key, String text) {  
    46.         String ret = null;  
    47.         StringBuilder buf = new StringBuilder();  
    48.         int m, k, s = table.length(),   
    49.                   e = text.length(),   
    50.                   ke = key.length();  
    51.   
    52.         for(int i = 0; i < e; i += 1) {  
    53.             m = dict(text.charAt(i), reverse);  
    54.             k = dict(key.charAt(i % ke), false);  
    55.             if (m < 0 || k < 0break;  
    56.             m = m + k + i;  
    57.             buf.append(dict(m % s, reverse));  
    58.         }  
    59.         if (buf.length() == e)  
    60.             ret = buf.toString();  
    61.         return ret;  
    62.     }  
    63.     public String encode(String key, String text) {  
    64.         return crypto(false, key, text);  
    65.           
    66.     }  
    67.     public String decode(String key, String text) {  
    68.         return crypto(true , key, text);  
    69.     }  
    70.     public static void main(String[] args) {  
    71.         Vigenere vigenere = new Vigenere();  
    72.         String data = vigenere.encode("BELLASO""APPLE");  
    73.         vigenere.decode("BELLASO", data);  
    74.     }  
    75. }

    話說,Vigenere加密算法傳入的密鑰到不是一個數字,是一個字符串。這個字符串中所用的字符,必須在替換表中出現過的。總的來說,Vigenere的強度要比Caesar強一些。但是終究還是會被破解的。不過,Vigenere有機會成為強度相當高的一種加密手段,前提是~前提是你的密鑰長度大于或等于明文長度。然而,在實際應用中,這個密鑰總是小于明文長度的。

      4、總結

      總的來說,理解這兩個加密算法都不算太難。對于密碼學大牛來說,這簡直是小兒科了。兩個算法有許多地方都是公用的,只是在一些地方有少許不同。在開發中,可以根據自己的喜好選擇一下。不要期待這兩個加密算法能有多大的抗破解強度,但是,作為一個煙霧彈掩蓋一下明文還是可以的。不過,如果你要將這個加密算法反復對一組明文加密的話,你最好自己再測試一下。因為,加密次數多了,出來的不一定是一個強度高的密文,也可能會是明文本身,切記切記。

      另外,有些人可能會想,那如果我要加密的是中文或者二進制數據,是不是要建立一個超大的密碼表,比如把中文字符集放進去?我想說的是,這個加密算法強度不是很高的,如果你非有這個需求,要上身穿著阿瑪尼,腳上穿著丁子拖加褲衩,那也是可以的,方法就是用Base64把你的數據轉一下碼。剩下的就是傳一個包含那64個字符的轉換表。建議“=”符號不要加密。

      就像我題目所說的,聊勝于無。有時候,有條褲衩穿著出門,總比一絲不掛的出門要好。前者,你最多是被人說不太文明。而后者,你卻鐵定要被請去喝茶的。我實現這兩個密碼最主要的現實意義也在于此,最后,感謝你能堅持看到文章的末尾,如果你有什么疑問或者想法,希望你能告訴我,我也很樂意與你交流。

    posted on 2011-11-07 10:32 順其自然EVO 閱讀(338) 評論(0)  編輯  收藏 所屬分類: 新聞

    <2011年11月>
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 一区二区免费在线观看| 免费人成视频在线观看不卡| 无遮挡呻吟娇喘视频免费播放| 久久精品国产亚洲5555| 最近的中文字幕大全免费版| a级片免费在线播放| 亚洲成av人无码亚洲成av人| 亚洲成色在线影院| 久久亚洲高清综合| 免费人成年激情视频在线观看| 国产一卡2卡3卡4卡2021免费观看 国产一卡2卡3卡4卡无卡免费视频 | 黄色免费网址大全| 亚洲欧洲精品成人久久曰| 四虎1515hh永久久免费| a级日本高清免费看| 色哟哟国产精品免费观看| 十八禁无码免费网站| 亚洲AV日韩AV无码污污网站| 亚洲jjzzjjzz在线观看| 1区1区3区4区产品亚洲| 亚洲免费人成视频观看| 久久久久免费看成人影片| 国产做国产爱免费视频| 国产精品免费看久久久香蕉| 黄页网址在线免费观看| 成人亚洲国产精品久久| 国产亚洲精品VA片在线播放| 亚洲国产午夜精品理论片| 亚洲精品第一国产综合精品| 亚洲欧洲国产精品你懂的| 久久久亚洲精品无码| 亚洲国产香蕉碰碰人人| 亚洲邪恶天堂影院在线观看| 亚洲国产精品婷婷久久| 中文字幕亚洲免费无线观看日本| 亚洲人成网www| 亚洲最大视频网站| 亚洲一区二区三区免费观看| 亚洲色欲色欲www| 国产亚洲国产bv网站在线| 亚洲精品又粗又大又爽A片|