2014-10-08 177 views
0

在處理一些代碼庫時,我試着理解一段代碼以便能夠工作和定製它,我能夠理解近90%的代碼流。這裏是整體流程瞭解一段Java代碼

  1. 碼被用來生成15位代碼(字母數字),前3位是客戶提供。
  2. 最初代碼是生成16位數的字母數字數字並將其存儲在緩存中。
  3. 客戶可以通過指定數量生成任意數量的代碼。
  4. 所有客戶生成的代碼都是從16位數字(點2)生成的。所有生成的代碼都有來自該16位數字字母數字的數字/字母。
  5. 當有人試圖使用這些代碼時,系統試圖驗證提供的代碼是否有效。

我觸擊了在用於確定是否所提供的代碼是否有效,這裏的邏輯是,一段代碼,我被生成並存儲在生成6個碼作爲樣品,在這種情況下的字母數字代碼高速緩存是

initial-alphabet : M9W6K3TENDGSFAL4 

代碼來生成基於initial-alphabet是 myList中= [123-MK93-ES6D-36F3, 123-MK93-EFTW-D3LG, 123-MK93-EALK-TGLD, 123-MK93-ELKK-DN6S, 123-MK93-E4D9-3A6T, 123-MK93-EMTW-LNME]

protected int getVoucherNumber(String voucherCode){ 
    int voucherNumberPos = voucherCode.length() - 12; 
    String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6); 
    int firstByte = getIntFromHexByte(voucherNumberHex.substring(0, 2), 0); 
    int secondByte = getIntFromHexByte(voucherNumberHex.substring(2, 4), 1); 
    int thirdByte = getIntFromHexByte(voucherNumberHex.substring(4, 6), 7); 
    return firstByte << 16 | secondByte << 8 | thirdByte; 
} 

private int getIntFromHexByte(String value, int offset){ 
    return (getIntFromHexNibble(value.charAt(0), offset) << 4) + getIntFromHexNibble(value.charAt(1), offset + 4); 
} 

private int getIntFromHexNibble(char value, int offset){ 
    int pos = getAlphabet().indexOf(value); 
    if (pos == -1) {// nothing found} 
    pos -= offset; 
    while (pos < 0) { 
    pos += 16; 
    } 
    return pos % 16; 
} 

這裏是其試圖驗證共同的代碼德

int voucherNumber = getVoucherNumber(kyList.get(4)); 

voucherNumber這種情況下的值是4即,從列表中的第四元素,在情況下,我通過這是不列表getVoucherNumber方法的一部分返回一個較高的值(比表計數值的任何值)。

之一,其困惑我最主要的事情是這兩條線

int voucherNumberPos = voucherCode.length() - 12; 
String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6); 

按我的理解,他們首先移動了從這些客戶提供的,但他們又沒有使用檢查前3位字符串的其餘部分,但只是字符串的特定部分。

任何一個可以幫助我瞭解這個

+2

爲什麼被標記爲java8?此代碼示例中是否有關於Java 8的特定內容?我沒有看到它,但也許我錯過了它... – FrustratedWithFormsDesigner 2014-10-08 18:38:04

+0

@FrustratedWithFormsDesigner:沒有任何與java-8相關的,我錯誤地標記它,謝謝糾正 – 2014-10-09 01:58:25

回答

5

看來你繼承了一些寫得不好的代碼的責任。我們都在那裏,所以我會盡力回答。我不太樂觀,這個問題是針對本網站的主題,但它似乎並未被幫助中心禁止。爲了保持主題不變,我將結束一些一般性建議,不僅限於問題的高度局部化的細節。

myList.get(4) 

數組在Java中是從零開始,所以這是123-MK93-E4D9-3A6T。你可能知道這一點,但從你的問題來看你並不清楚。

initial-alphabet : M9W6K3TENDGSFAL4 

我想這是什麼在getIntFromHexNibble調用getAlphabet返回。所以代碼中的字母數字字符應該是十六進制的,但對於數字使用非標準的16個字符。

protected int getVoucherNumber(String voucherCode){ 

忽略連字符和客戶提供的前三位數字,代碼是'MK93E4D93A6T'。十二個十六進制數字編碼48位,但在Java中的int只有32位長,所以代碼已被破壞。無論它做什麼,它都不會返回代金券代碼所代表的代金券號碼。

int voucherNumberPos = voucherCode.length() - 12; 
String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6); 

這被設置voucherNumberHex到六個字符的長字符串,從voucherCode末端開始12,在這種情況下93-E4D。在編寫代碼時,似乎作者不希望調用者包含連字符。即使如此,意圖似乎是忽略了一半的代金券代碼。

int firstByte = getIntFromHexByte(voucherNumberHex.substring(0, 2), 0); 
int secondByte = getIntFromHexByte(voucherNumberHex.substring(2, 4), 1); 
int thirdByte = getIntFromHexByte(voucherNumberHex.substring(4, 6), 7); 

這看起來簡單的在第一,但,參數01,並且7不偏移,在所有儘管參數的名稱。它試圖將每一對十六進制數字轉換成一個字節,如果不是連字符,這將是明智的。現在有趣的部分:

private int getIntFromHexNibble(char value, int offset) { 
    int pos = getAlphabet().indexOf(value); 
    if (pos == -1) {// nothing found} 
     pos -= offset; 

     while (pos < 0) { 
      pos += 16; 
     } 
     return pos % 16; 
    } 

「找到」後的右大括號已被註釋掉,所以您發佈的代碼實際上是不完整的。我要去假設有這​​麼讀

return pos; 
} 

所以基本思想是M變爲0另一條線或兩個,9變爲1,依此類推通過調用indexOf。但是如果這個方法看到一個字符不在提供的字母表中,就像連字符一樣,它使用所謂的offset來計算一個默認值(在這個例子中是14,如果我在腦子裏做了數學計算),並且返回作爲十六進制的半字節值。

最終的結果是,您將取回範圍爲0(含)至2^24(不含)的數字。但是這樣的數字應該有2^24個可能的值,只有2^20個不同的值會被返回。因此,看起來像基數爲32的十二位數字的代金券代碼,其數值將會是天文數字,因此每個客戶前綴內的代碼數量限制在一百萬以上。

一般建議:

  • 使用同行審查,以防止這樣的代碼進入 生產。
  • 使用單元測試來證明代碼做的功能 名稱說明。
  • 如果輸入不是 ,那麼使用異常提前失敗。
+0

同行評審只有在他們不進入肚臍考試,這是他們隨着時間的推移,幾乎沒有例外。配對是更好的海事組織 - 這是一個更好的平衡「銳化斧頭」和「完成東西」比大多數同行評審。 一個大腦可以解決一個問題,兩個可以很好地解決問題,三個只能稍微好一點,到了四個大腦的時候,你大多隻是在浪費金錢和時間。 – Calphool 2014-10-08 20:45:47

+0

@JoeRounceville我同意讓一個或兩個以上的人審閱給定的代碼往往是徒勞的。我的組織只爲了知識轉移或展示原型方法而做到這一點。同行評審與我們一樣,是每個人的代碼由其中一個或兩個同行評審。 – gatkin 2014-10-08 21:03:38

+0

@gatkin:謝謝你的回覆,不幸的是我不能改變這段代碼:(。如果(pos == -1){}',這裏有一個異常正在返回。我感到困惑的是關於憑證的部分代碼被用於驗證,因爲代碼沒有獲得完整的憑證代碼,而只是其中的特定部分。你認爲這背後有什麼邏輯嗎? – 2014-10-09 02:29:37