簡體   English   中英

了解一段Java代碼

[英]Understanding Piece of Java code

在使用某些代碼庫時,我試圖理解一段代碼,以便可以工作和自定義它,我幾乎可以理解90%的代碼流。 這是整體流程

  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位數字,但他們又一次沒有使用字符串的其余部分,而只使用了字符串的特定部分。

誰能幫我理解這一點

看來您已經繼承了編寫某些不良代碼的責任。 我們到過那里,所以我會嘗試本着這種精神回答。 我不太確定這個問題是該網站的熱門話題,但幫助中心似乎並未禁止該問題。 為了保持話題性,我將給出一些一般性建議,這些建議不僅限於問題的高度本地化的細節。

myList.get(4)

Java中的數組是從零開始的,因此是123-MK93-E4D9-3A6T 您可能知道這一點,但是從您的問題中尚不清楚您是否確實如此。

initial-alphabet : M9W6K3TENDGSFAL4

我假設這是getAlphabet中對getAlphabet的調用返回的getIntFromHexNibble 因此,代碼中的字母數字字符應為十六進制,但對數字使用非標准的16個字符集。

protected  int getVoucherNumber(String voucherCode){

忽略連字符和客戶提供的前三位數字,代碼為“ MK93E4D93A6T”。 12個十六進制數字編碼48位,但是Java中的int僅32位長,因此該代碼已被破壞。 無論執行什么操作,都不會返回憑單代碼表示的憑單編號。

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

這會將voucherNumberHex設置為一個六個字符的長字符串,從voucherCode的末尾開始十二個voucherCode ,在本例中為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變為9變為1,依此類推,通過調用indexOf 但是,如果此方法看到的字符不在所提供的字母中(例如連字符),則使用所謂的offset來計算默認值(在本例中為14,如果我已經正確計算過算術),然后返回作為十六進制半值。

最終結果是您得到一個介於0(含)到2 ^ 24(不含)之間的數字。 但是在這樣一個數字應具有的2 ^ 24個可能值中,將僅返回2 ^ 20個不同的值。 因此,如果憑證代碼看起來像以32為基數的十二位數字,並且會具有天文數字的值,則每個客戶前綴中的憑證編號將被限制在一百萬以上。

一般建議:

  • 使用同行評審來防止此類代碼投入生產。
  • 使用單元測試來證明代碼可以實現功能名稱所說明的功能。
  • 如果輸入不是您期望的值,請使用異常使早期失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM