1、背景介紹
話說目前做所謂“企業”開發的語言基本就集中在運用.net和j2ee上了。又話說,在下很不幸又和java“同流合污”了一把。現在回想起來,真是感慨萬千啊~遙想公瑾當年,小喬初嫁了,雄姿英發,羽扇綸巾,談笑間,強虜灰飛煙滅。~
額,下面插播一下正題。其實,目前國内用java做真正的“企業級”得其實并不是很多,絕大多數都是用個ssh1就覺得這就是java之企業級開發了,之後就開始沾沾自喜了。這你說讓servlet和ejb3情何以堪啊~是以說,目前國内大多數java的開發環境并不能說真正的武裝到牙齒。
那麼,處于對易用性,易實作性的考慮,那些什麼des算法就暫時不考慮了。如果真有這個需求的話,相信找個健壯性很高的des問題還不是很大的。而在那許多經典的加密算法中,要數caesar加密比較經典了。是以,處于這樣的一個需求,就打算實作一個經典加密算法。
2、caesar加密算法
caesar加密算法算是經典加密算法中最簡單的了。對于标準的caesar來說,就是把字母序列向後移動一定的數量,替換後得到密文,而這個數量為固定值3。也就是說,在都是由英文字母組成的文本裡,字母a将會被替換成d,b會被替換成e,以此類推。
對于caesar加密算法,存在幾點問題。首先是這個作為密鑰的值是個固定的3,而且字母表又是按順序排列的,是以隻要對方知道你是用caesar加密的,就很容易的脫密成原文,雖然有些麻煩,但是這就和用原文是差不多的,即使對加密要求很低也不能低成這樣不是?然後是這個替換表,因為是基于字母表的,是以對于英文來說隻能加密英文字母,這樣就不能被支援了。最後,因為替換是固定的,是以,對于同一個字母,加密後的字母也是固定的。比如“aaa”這個文本加密後,就是“ddd”,看起來還不夠迷惑人。
基于以上的原因,我這裡實作的caesar做了一些修改,但是總的思路還是caesar。
public class caesar {
private string table;
private int seeda = 1103515245;
private int seedb = 12345;
public caesar(string table, int seed) {
this.table = chaos(table, seed, table.length());
}
public caesar(string table) {
this(table, 11);
public caesar() {
this(11);
public caesar(int seed) {
this("abcdefghijklmnopqrstuvwxyz", seed);
public char dict(int i, boolean reverse) {
int s = table.length(), index = reverse ? s - i : i;
return table.charat(index);
public int dict(char c, boolean reverse) {
int s = table.length(), index = table.indexof(c);
return reverse ? s - index : index;
public int seed(int seed) {
long temp = seed;
return (int)((temp * seeda + seedb) & 0x7fffffffl);
public string chaos(string data, int seed, int cnt) {
stringbuffer buf = new stringbuffer(data);
char tmp; int a, b, r = data.length();
for (int i = 0; i < cnt; i += 1) {
seed = seed(seed); a = seed % r;
seed = seed(seed); b = seed % r;
tmp = buf.charat(a);
buf.setcharat(a, buf.charat(b));
buf.setcharat(b, tmp);
}
return buf.tostring();
public string crypto(boolean reverse,
int key, string text) {
string ret = null;
stringbuilder buf = new stringbuilder();
int m, s = table.length(), e = text.length();
for(int i = 0; i < e; i += 1) {
m = dict(text.charat(i), reverse);
if (m < 0) break;
m = m + key + i;
buf.append(dict(m % s, reverse));
if (buf.length() == e)
ret = buf.tostring();
return ret;
public string encode(int key, string text) {
return crypto(false, key, text);
public string decode(int key, string text) {
return crypto(true , key, text);
public static void main(string[] args) {
caesar caesar = new caesar();
string data = caesar.encode(32, "apple");
caesar.decode(32, data);
}
在上面的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上存在的一些問題。但是,我的實作還是做了一些小小的調整。
public class vigenere {
public vigenere(string table, int seed) {
public vigenere(string table) {
public vigenere() {
public vigenere(int seed) {
private char dict(int i, boolean reverse) {
private int dict(char c, boolean reverse) {
private int seed(int seed) {
string key, string text) {
int m, k, s = table.length(),
e = text.length(),
ke = key.length();
k = dict(key.charat(i % ke), false);
if (m < 0 || k < 0) break;
m = m + k + i;
public string encode(string key, string text) {
public string decode(string key, string text) {
vigenere vigenere = new vigenere();
string data = vigenere.encode("bellaso", "apple");
vigenere.decode("bellaso", data);
話說,vigenere加密算法傳入的密鑰到不是一個數字,是一個字元串。這個字元串中所用的字元,必須在替換表中出現過的。總的來說,vigenere的強度要比caesar強一些。但是終究還是會被破解的。不過,vigenere有機會成為強度相當高的一種加密手段,前提是~前提是你的密鑰長度大于或等于明文長度。然而,在實際應用中,這個密鑰總是小于明文長度的。
4、總結
總的來說,了解這兩個加密算法都不算太難。對于密碼學大牛來說,這簡直是小兒科了。兩個算法有許多地方都是公用的,隻是在一些地方有少許不同。在開發中,可以根據自己的喜好選擇一下。不要期待這兩個加密算法能有多大的抗破解強度,但是,作為一個煙霧彈掩蓋一下明文還是可以的。不過,如果你要将這個加密算法反複對一組明文加密的話,你最好自己再測試一下。因為,加密次數多了,出來的不一定是一個強度高的密文,也可能會是明文本身,切記切記。
另外,有些人可能會想,那如果我要加密的是中文或者二進制資料,是不是要建立一個超大的密碼表,比如把中文字元集放進去?我想說的是,這個加密算法強度不是很高的,如果你非有這個需求,要上身穿着阿瑪尼,腳上穿着丁子拖加褲衩,那也是可以的,方法就是用base64把你的資料轉一下碼。剩下的就是傳一個包含那64個字元的轉換表。建議“=”符号不要加密。
就像我題目所說的,聊勝于無。有時候,有條褲衩穿着出門,總比一絲不挂的出門要好。前者,你最多是被人說不太文明。而後者,你卻鐵定要被請去喝茶的。我實作這兩個密碼最主要的現實意義也在于此,最後,感謝你能堅持看到文章的末尾,如果你有什麼疑問或者想法,希望你能告訴我,我也很樂意與你交流。
本文出自seven的測試人生公衆号最新内容請見作者的github頁:http://qaseven.github.io/