2011-12-14 81 views
4

我最近從德爾福2007年拿了一些代碼,並將其升級到德爾福2009年。這可能也可能不相關。爲什麼在升級到Delphi 2007之後,我的加密工作不能正常工作?

但是當我在我的電腦上運行密碼時,密碼的解密不能正確解密。這是代碼。

Seed := GenerateIntFromString('usercode'); 

// Check if a password already exists 
if TableUser.FieldByName('PASSWORD').AsString <> '' then 
begin 
    EncodedPassword := TableUser.FieldByName('PASSWORD').AsString; 
    DecodedPassword := EncryptDecrypt(EncodedPassword, Seed); 
//etc.. And the function 

function TLogonForm.EncryptDecrypt(Input: string; Seed: integer) : string; 
var 
i : integer; 
Output : string; 
begin 
    RANDSEED := Seed; 
    Output := ''; 
    for i := 1 to Length(Input) do 
     Output := Output + Chr(Ord(Input[i]) XOR (RANDOM(254) + 1)); 
    Result := Output; 
end; 

所以,如果我的用戶代碼是TD ,我的密碼是 'JOEJOE'

加密的密碼是:I AP?

解密的passowrd是:JìEJùE

應該爲JOEJOE明顯解密。踢球者,如果我建立的代碼,併發送到另一個用戶的exe解密罰款。這使我相信它的代碼沒有問題,而與我的電腦有些異常。會是什麼呢?


你可以忽視這一點,因爲它可能不相關。我只提到它,因爲這是另一種情況,在一臺計算機上可以正常工作,而另一臺計算機卻可以。

但也有嘗試設置過濾器時,其中一個案例

TableUser2.Filter := FilterString; 

它工作正常,我,但其他用戶得到一個錯誤。

TableUser2:錯誤3106:在記錄過濾器表達式中發現不支持的操作符。

即使當我們使用相同的代碼進行過濾時,也是如此。也許是數據庫問題?

+5

我懷疑你告訴我們的代碼不是唯一的破解代碼。您的方法EncryptDecrypt沒有正確地從非Unicode Delphi移植到Unicode Delphi。你知道當然是一個字符串和一個字符,每個字符的字節大小,現在每個字符兩個字節? –

+0

資源:http://stackoverflow.com/questions/1598211/delphi-conversion-unicode-issues –

+0

我其實沒有意識到這一點。我剛剛開始使用此代碼。加密經驗有限。 Char信息如何幫助我?感謝p.s.我有你的鏈接。 – Trevor

回答

7

嘗試從ANSI做端口UNICODE這樣的:

function TLogonForm.EncryptDecrypt(Input: AnsiString; Seed: integer) : AnsiString; 
var 
i : integer; 
Output : AnsiString; 
begin 
    RANDSEED := Seed; 
    Output := ''; 
    for i := 1 to Length(Input) do 
     Output := Output + AnsiChar(Ord(Input[i]) XOR (RANDOM(254) + 1)); 
    Result := Output; 
end; 

我最好的野生的猜測是,預期的結果,因爲ANSIChar類型和UnicodeChar之間的差別是不同的。如果您設法生成一些無法存儲在數據庫的非Unicode數據字段中的無效代碼點,則可能會出現一些有趣的錯誤。

+0

這裏沒有添加250到250。唯一的'+'是字符串連接。我期望Q中的代碼因代碼頁不匹配而中斷。 –

+3

您可能想要確保您可以解密較舊的密碼,因爲Delphi說'注意:因爲Random函數的實現可能會在編譯器版本之間發生變化,所以我們不推薦使用Random進行加密或其他需要可重複序列的僞隨機數字。' –

+0

好想我會研究它。 – Trevor

0

我會做的第一件事就是對你的函數的輸入/輸出進行一些記錄。

這聽起來好像是在兩種情況下,TableUser.FieldByName(「Password」)中的值不會傳遞您期望的值。

我會注意的另一件事是兩臺機器使用的數據庫排序規則。我假設你的兩個測試用例之間的底層數據庫是不同的;或者,至少,連接字符串信息具有不同的排序值。這肯定會甩掉解密。

+0

在德爾福2007和德爾福2009之間,這個傢伙並不知道從Char = byte到Char = 2個字節的語言變化。他有更多的問題,他甚至還沒有意識到。 –

+0

@WarrenP:我同意。我的答案在這裏不重要。 – NotMe

+0

感謝您的幫助。 – Trevor

1

你的問題是德爾福2009年的文字使用Unicode而不是ANSI。這是一個重大的突破性改變,需要大量的移植工作。您不僅需要處理代碼中的編碼問題,還需要升級您使用的任何第三方組件。

可以恢復到以前的行爲像這樣這個特殊的功能:

function TLogonForm.EncryptDecrypt(Input: AnsiString; Seed: integer): AnsiString; 
var 
i : integer; 
Output : AnsiString; 
begin 
    RANDSEED := Seed; 
    Output := ''; 
    for i := 1 to Length(Input) do 
     Output := Output + AnsiChar(Ord(Input[i]) XOR (RANDOM(254) + 1)); 
    Result := Output; 
end; 

在2009年德爾福的string數據類型是UTF-16編碼字符串。以前版本的Delphi的ANSI編碼字符串被命名爲AnsiString。同樣,Chr()會生成16位但WideChar字符,但您需要AnsiChar,8位ANSI字符類型。


但是,肯定會有其他一些問題需要解決。我建議你閱讀MarcoCantù的白皮書Delphi and Unicode。在進一步瞭解本文之前,您應該首先了解本文詳述的問題。

+0

我會檢查兩個答案是正確的,但我不能。謝謝! – Trevor

+0

@Trevor沒有probs。你只需要接受最好的一個,你可以決定哪個最好!這就是它的原因。 –

相關問題