2011-06-15 63 views
5

我即將使用算法對可變長度進行編碼,但非常長字符串從XML文件中檢索字段,然後該編碼數據應該保留在數據庫中。後來,當我收到第二個文件時,我需要從數據庫(先前存儲的)中獲取編碼數據,然後對其進行解碼並使用新數據進行驗證以進行重複。Java中BASE64類的編碼/解碼算法的效率如何?

我試圖org.apache.commons.codec.binary.Base64類 它有2種方法:

  1. encodeBase64(Byte[] barray)
  2. decodeBase64(String str)

這工作完全正常,解決了我的問題。 但它將55個字符串轉換爲6個字符串。

所以我不知道是否有任何情況下,這些算法編碼2個字符串非常大,只有1個字符不匹配(例如)到相同的編碼字節數組。

我不知道Base64班,但如果有人能幫助我,這將是非常有益的。

如果你可以建議任何其他的算法,使一個大的字符串短的固定長度和解決我的目的,我會很樂意使用它。

在此先感謝。

+0

任何正確執行的base64會讓一個String較大不小。你想壓縮字符串嗎? – 2011-06-15 09:50:26

+0

是的,實際上我需要一些算法來將一個長的字符串壓縮成一個較小的字符串並存儲在數據庫中,然後使它膨脹以獲得原始字符串。 我通過互聯網看到了ZipOutputStream類的實現,但我沒有嘗試。 – 2011-06-15 09:58:27

+0

我想你正在尋找一個哈希函數,如[MD5](http://en.wikipedia.org/wiki/MD5)(它將所有輸入轉換爲128字節的輸出)。 Base64編碼通常會導致輸出大小爲輸入大小的四分之三,因此根本不會導致定長輸出。 – 2011-06-15 09:58:46

回答

12

效率不高。

此外,使用sun.misc類給出了一個非便攜式應用程序。

退房從MiGBase64下列性能比較:

enter image description here


所以我不知道是否有地方 這些算法編碼2串 這是非常大的,只有有任何情況下, 1 字符不匹配(例如)到相同的 編碼的字節數組。

Base64不是散列算法,它是一種編碼,因此必須是雙向的。碰撞不能被允許 - 否則解碼將是非確定性的。 Base64旨在表示ASCII字符串中的任意二進制數據。將Unicode字符串編碼爲Base64通常會增加代碼點的數量,因爲Unicode字符集需要多個字節。 Unicode字符串的Base64表示形式取決於所使用的編碼(UTF-8,UTF-16)。例如:

Base64(UTF8("test")) => "dGVzdA==" 
Base64(UTF16("test")) => "/v8AdABlAHMAdA==" 

溶液1

使用無損壓縮

GZip(UTF8("test")) 

這裏要轉換的字符串,字節數組,並使用無損壓縮來減少字節數你必須存儲。你可以改變字符編碼和壓縮算法來減少這取決於你要存儲的字符串的字節數(即如果它主要是ASCII然後UTF-8可能會是最好的

優點:沒有衝突,能力以恢復原始的字符串
缺點:需要存儲值中的字節是可變的;存儲值所需要的字節是較大

溶液2

使用散列算法

SHA256(UTF8("test")) 

在這裏,您將字符串轉換爲具有哈希函數的固定長度的字節集合。散列是單向的,其性質爲collisions can be possible。然而,根據您希望處理您可以選擇一個哈希函數,以儘量減少衝突的可能性串的分佈和數量

優點:字節來存儲值是固定的要求;字節所需要的存儲值小
缺點:碰撞可能,沒有能力恢復原始字符串

+0

@johnstok我明白你的意思,謝謝你的信息 – 2011-06-15 10:22:39

+0

@johnstok你能告訴我一種有效壓縮和解壓縮字符串的方法嗎? – 2011-06-15 10:35:47

+0

@ johnstok非常感謝:) – 2011-06-15 11:58:45

1

我剛纔看到您的評論 - 看來你實際上是尋找壓縮,而不是哈希以我最初以爲。雖然在這種情況下,不會能夠獲得任意輸入的固定長度輸出(想想看,無限數量的輸入不能映射到有限數量的輸出),所以我希望這不是一個強烈的要求。

在任何情況下,您選擇的壓縮算法的性能將取決於輸入文本的特性。在沒有進一步的信息的情況下,DEFLATE壓縮(由Zip輸入流,IIRC使用)是一個很好的通用算法,並且至少用作比較的基礎。不過,爲了便於實施,您可以使用內置於JDK中的Deflator類,該類使用ZLib壓縮。

如果你的輸入字符串有特定的模式,那麼不同的壓縮算法可能會或多或少地有效。一方面,如果您不打算讓壓縮數據被任何其他進程讀取,則使用哪一個並不重要 - 只要您可以自行壓縮和解壓縮,它就會對您的客戶端透明。

這些其他問題可能感興趣的:

+0

首先感謝你的建議,我明白你的意思.Base64在這裏解決了我的目的,但我所關心的是我可以依靠Base64算法是否足夠有效地對所有較大的字符串進行編碼和解碼。是否會有任何情況下Base64算法爲大字符串生成相同的輸出,這些字符串只有一個字符左右的不同? – 2011-06-15 10:13:31

+0

**是否** base64解決你的目的?我以爲你想讓字符串更小 - base64會導致*更大*的輸出。而且它也不會在輸出大小上設置任何上限 - 如果輸入爲3000個字符,則編碼輸出將爲4000個字符,因此這可能會導致您對「對所有較大字符串進行高效編碼」的要求失敗。儘管如此,在回答你最後一個問題時,不會有任何碰撞; base64是完全雙向的。 – 2011-06-15 10:33:40

+0

是的,我很抱歉,我最初認爲Base64類壓縮輸出。但後來發現java.util.zip.Deflater和java.util.zip.Inflater類是我需要的,但又一次卡住了壓縮字符串的輸出,它不是Unicode格式。我試圖將其轉換爲UTF8,但在eclipse控制檯上顯示的字符串字面值不是UTF8格式。我將不得不查看這些數據是否可以保存到我的Oracle數據庫中。無論如何感謝您的幫助:)歡呼聲。 – 2011-06-16 05:57:53