面試程式設計基本功的時候,很常見的乙個題目是:
判斷兩個字串是否完全相同?
很多同學能夠很快的寫出對應的**:
public static boolean isequal(byte a, byte b)
// 乙個乙個字元,迴圈遍歷判斷
for (int i = 0; i < a.length; i++)
}// 全部字元相同,返回true
return true;
}
**沒有問題,甚至jdk底層,也是這麼實現的。
然而,messagedigest.isequal卻被報了bug,並在jdk 1.6.0_17中被fix成了以下的版本:
public static boolean isequal(byte a, byte b)
// 返回結果初始化
int result = 0;
// 乙個乙個字元,迴圈遍歷判斷
for (int i = 0; i < a.length; i++)
// 返回結果為0,說明字串全部相同,返回true
return (result == 0);
}
首先,字元比較,公升級成了「按位異或」。
這個不難理解,對於兩個字元x和y:
(1)如果x == y,則有 x^y == 0
(2)如果x != y,則有 x^y != 0
其次,就**的正確性來說,新**並沒有問題:
(1)當所有字元都相同時,result必為0,兩個字串才完全相同,返回true;
(2)只要有兩個字元不同,result必不為0,一定會返回false;
同時,當輸入的引數,是兩個相同的字串時,新舊演算法的時間複雜度是相同的:都需要遍歷每乙個字元,然後返回true。
可是,當輸入的引數,是兩個不同的字串時:
(1)舊版本**,只要發現兩個字串有1個字元不同,直接返回false;
(2)新版本**,會堅持檢查完所有字元,再返回false;
這裡大家就要有疑問了,新版本的**,效能不是降低了嗎?
要更徹底的解釋這個問題,先得從計時攻擊(timing attack)說起。
傳統的hacker,如何破解密碼?
最常見的,採用暴力窮舉破解。但當密碼位數較長,字元值域較廣的時候,破解難度較大。
新型計時攻擊(timing attack),是怎麼破解密碼?
第一步,要猜測密碼的長度。
hacker不停的測試不同長度的「探測密碼」,然後對執行時間進行計時。
hacker可以使用:
a
aaaaa
aaaa
...
作為探測密碼。 比較字串
其實這是在 c 從入門到精通 上摘抄的,由於不知道漢字怎麼排序,就查了查書,寫在這裡也可以幫助其他初學者更方便的找到漢字的排序方法。用於排序 int compare string str1,string str2 int compare string str1,string str2,bool ig...
字串比較
題目是這樣的 比較兩個字串,忽略大小寫,比較長度不超過n,比較順序為字典序。返回如下 0 s1 s2 0 s1 s2 0 s1 首先我們會先寫乙個函式名,我想大部分同學會寫成如下形式 int strncompare char s1,char s2,int n 是的,我開始也是這樣寫的。可是我突然覺得...
字串比較
1.publicstaticbooleanisempty string str 判斷某字串是否為空,為空的標準是 str null或 str.length 0 下面是 stringutils 判斷是否為空的示例 stringutils.isempty null true stringutils.is...