字串比較,居然暗藏玄機

2021-10-07 20:07:03 字數 1374 閱讀 3187

面試程式設計基本功的時候,很常見的乙個題目是:

判斷兩個字串是否完全相同?

很多同學能夠很快的寫出對應的**:

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...