2012-10-17 29 views
1

我知道有幾十個問題已經以各種形式出現。我的問題稍微更直接。使用Free Pascal和DecodeStringBase64驗證Base64輸入

使用免費Pascal和s:= DecodeStringBase64(s);函數,無論如何要驗證傳遞爲s的解碼字符串是否真正從合適的Base64輸入數據解碼,以避免解碼垃圾?

我所做的最好的是使用reg exp來識別潛在的Base64數據(from the accepted answer here)。然後我使用mod檢查它是否可以被4整除。如果它可以被4整除,我將它傳遞給DecodeStringBase64。但是,儘管與reg exp匹配,但我仍然得到很多誤報,並返回了「已解碼」但顯然不是Base64的數據。例如「WindowsXP =」與表達式匹配,但不是Base64編碼的數據。同樣,名字'Ted'編碼爲VGVk,它甚至沒有通常的'='填充(這可以幫助將其標記爲頁腳),但它仍然是我想要的潛在Base64片段找到並解碼。

在PHP中,有base64_decode(),其中可以傳遞true參數以幫助驗證。

AFAIK,免費Pascal沒有這與DecodeStringBase64,我需要一些驗證方式。周圍的解碼和編碼的主題

其他有用的回覆,如果讀者碰巧尋找它,因爲我是昨天,是here

回答

2

簡短的回答是否定的,沒有100%的工作確認爲Base64編碼字符串。

Base64編碼字符串的=標誌不是顯著,它是padding,所以它並不總是需要在那裏(編碼字符串只是在長度上多4)。只能檢查字符串長度是4的倍數,檢查Base64字母表中的有效字符(請參閱Page 5, Table 1),並驗證輸入字符串末尾是否有不止兩個填充符號字符。這裏有一個代碼,可以驗證,如果傳遞的字符串可以是一個有效的Base64編碼的字符串(僅此而已,你可以做,反正):

function CanBeValidBase64EncodedString(const AValue: string): Boolean; 
const 
    Base64Alphabet = ['A'..'Z', 'a'..'z', '0'..'9', '+', '/']; 
var 
    I: Integer; 
    ValLen: Integer; 
begin 
    ValLen := Length(AValue); 
    Result := (ValLen > 0) and (ValLen mod 4 = 0); 
    if Result then 
    begin 
    while (AValue[ValLen] = '=') and (ValLen > Length(AValue) - 2) do 
     Dec(ValLen); 
    for I := ValLen downto 1 do 
     if not (AValue[I] in Base64Alphabet) then 
     begin 
     Result := False; 
     Break; 
     end; 
    end; 
end; 
+0

Afaik最後還有關於= chars的要求。 –

+0

@Marco,如果在編碼字符串的末尾有超過2個'='字符,你應該忽略它們,但是我猜'DecodeStringBase64'沒有這樣做......我還要添加檢查if末尾的'='字符數不超過2個字符。感謝您指出了這一點!無論如何,當在字符串結尾之前找到'='char時,它應該也被視爲無效... – TLama

+0

My Reg Exp是:Base64StringPattern.Expression:='([A-Za-z0-9 +/] {4})*([A-ZA-Z0-9 +/{2} == | [A-ZA-Z0-9 + /] {3} =)';所以,傳遞給你寫TLama函數的字符串在理論上只會在它們的末尾有一個或兩個=符號。雖然我認爲要在FPC中實施(正如Marco在下面所述),但在整個字符串中進行檢查是必要的。非常感謝您的幫助。 –

1

在接下來的版本(2.6.2),該DecodeStringBase64將有一個調用嚴格模式的額外布爾參數。 (它已經在「流」版本中可用)。

如果存在驗證錯誤,則會拋出異常。

+0

Thankyou Marco。當我提出的一個問題證明對FPC \ Lazarus的整體發展是適當和有益的時候,我總是鬆了一口氣。 –