2012-02-07 143 views
3

我想驗證本地數據庫(實際上是一個文件系統,但對於本次討論,我想保持這種簡單)。該數據庫具有以下屬性:生成可驗證的隨機數 - Java

它可以有1個或2個主鍵,它們必須是整數。 列可以是字符串(不允許ascii),整數,長或日期時間

我想驗證我要求此數據庫存儲的值是否與大量記錄(> 500k記錄)正確存儲。所以爲此,我想擴展一個生成數據的工具,以便日後輕鬆驗證。

所以基本上,說這是樣品模式:

pk1 (int - primary key) 
pk2 (int - primary key) 
s1 (string) 
l1 (long) 
i1 (int) 

我想產生500k的記錄用這個工具。然後,在任何時候,我都希望能夠對某條記錄進行完整性檢查。我可能會執行一系列操作(比如說備份,然後恢復數據庫),然後「抽查」幾條記錄。所以我希望能夠快速驗證記錄主鍵(pk1 = 100,pk2 = 1)的條目是否有效。

什麼是最好的方式去產生每列的值,以便以後可以很容易地驗證。這些值不必是完全隨機的,但它們也不應該經常重複,所以一些壓縮邏輯也可能被打中。

舉個例子,說「莫名其妙」的工具生成的行以下值:

pk1 = 1000 
pk2 = 1 
s1 = "foobar" 
l1 = 12345 
i1 = 17 

現在我執行一些操作,我想確認,在本月底,該行有沒有損壞。我必須能夠快速生成s1,l1和i1的期望值 - 給定pk1 = 1000和pk2 = 1 - 因此可以快速驗證它。

想法?

(我不能發佈的答案我自己的問題,因爲我是一個新的使用,從而增加這個:) 好了,我有可能的做法我可以追求:

方法1:使用 HASH(tablename)^ HASH(fieldname)^ pk1^pk2作爲種子。這樣,我可以在驗證時輕鬆計算每列的種子。另一方面,由於種子需要每列計算一次,因此在生成大量行的數據時可能會很昂貴。所以對於上面的模式,我會有500k * 3種子(產生500k記錄)。

方法2(由Philipp Wendler提議): 每行生成一個種子,並將種子存儲在該行的第一列中。如果第一列是int或long,則按原樣存儲該值。如果第一列是一個字符串,則將種子存儲在前x個字節中,然後使用該種子生成的字符將其填充到所需的字符串長度。

我更喜歡方法#2,因爲每行只有一個種子 - 使數據生成速度比方法1快一些。

+0

所以我想的更多的創造性的解決方案... 如果我生成種子是這樣的: 種子= HASH(表名)^ HASH(列名)^^PK1 PK2 現在我可以很容易地計算種子給定pk1和pk2,同時仍然保持東西在表格之間有點隨機... 列名可以在表中重複相同的pk1和pk2值...但從功能上講,它們應該具有相同的值.. – walletless 2012-02-07 19:11:52

+0

另一種選擇是追求Philipp Wendler在下面提出的建議: 使用表格的第一列來存儲使用的種子。如果這是一個int或long,只要將種子原樣存儲在其中即可。如果這是一個字符串,則使用前n個字節來存儲種子,並使用使用該種子生成的字符將字段填充到所需的長度。 – walletless 2012-02-07 19:26:31

+0

你也生成主鍵嗎?如果是,您可以使用它們來存儲其他列的散列。這可能會給你一些碰撞插入當然(但如果你隨機生成pk,這也可能發生) – wmz 2012-02-07 19:32:22

回答

0
+0

感謝穆斯特。我已經看過這個。問題在於使用「種子」值,所以我可以輕鬆生成字符串。 所以,本質上,這個問題是:給定pk1(1000)和pk2(1);什麼是我應該在隨機生成器中使用的種子,所以我可以每次都一致地爲s1,l1和i1創建相同的值。 – walletless 2012-02-07 18:51:28

+0

@walletless只需將種子存儲在其中一列中(與我在解決方案中提出的散列碼類似)。然後,您可以爲每行生成一個隨機種子,並從種子生成該行的數據。 – 2012-02-07 18:57:07

+0

該方法依賴於用於驗證的隨機數生成算法與用於生成的算法完全相同的事實。這聽起來很明顯,但可能是這種生成器的實現者並不能保證這一點,並且在未來稍微改變它們的算法(例如,在庫的下一個版本中)。那麼你的數據突然不會被驗證了。通過使用像任何常見散列碼一樣的標準化算法,問題就會消失。 – 2012-02-07 19:01:12

0

這個回答你的問題的只有第二部分的東西 - 有關使L1存儲所有其他領域的哈希值是什麼?然後,您可以快速驗證是否有任何損壞

+0

如果模式總是有很長的時間,這將工作。給定表格的一組列可以或不可以有任何長列 - 也可能有多個長列。修改任何現有的模式不是一種選擇,因爲有些應用程序依賴於特定形式的模式 - 修改它會使在生成的數據之上發生的任何功能測試失效。 – walletless 2012-02-07 19:01:23

1

您可以生成隨機數據,計算哈希碼(例如MD5,因爲它不需要密碼安全)並將哈希碼與數據一起存儲。您可以爲哈希代碼設置單獨的列,或者例如可以將其附加到任何字符串列。

爲了驗證,將存儲的散列碼與該行中其餘數據分開,重新計算散列碼並比較它們的相等性。如果它們不匹配,則數據已被修改。

這假定您只想保護您的數據不是意外修改(而不是來自惡意攻擊者)。

+0

不幸的是,修改架構不是一個選項。 我認爲的一個選擇是以一個固定的種子作爲應用程序的輸入,並將xk與pk1和pk2一起使用。然後用它作爲隨機的種子。 所以說,我使用輸入種子12345(它可以是任何東西 - 例如系統滴答聲)。因此,對我的隨機函數的種子將是12345^1000^1。然後使用隨機的apache共享,我可以產生每列。 該方法的問題是,我得到了幾行相同的值。 – walletless 2012-02-07 19:01:54

+0

是你的任意長度的字符串?你總是有一個字符串列?如果是這樣,只需在第一個字符串列的數據末尾追加散列碼(例如)。否則,您可以選擇一個或多個數字列(如果只存儲哈希代碼的某些位,則應該足夠多,例如64位)。 – 2012-02-07 19:05:12

+0

如果我使用這種方法,驗證工具只需要知道啓動輸入(本例中爲12345),並且可以輕鬆驗證給定pk1和pk2值的任何行。但是,問題是這會導致很多重複值。數據將生成100s的表格,所以如果我可以避免的話,我不想分別存儲每行的種子。 – walletless 2012-02-07 19:06:03