[英]Understanding Piece of Java code
在使用某些代碼庫時,我試圖理解一段代碼,以便可以工作和自定義它,我幾乎可以理解90%的代碼流。 這是整體流程
我對用於確定提供的代碼是否有效的邏輯感到震驚,這是那段代碼,我正在生成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);
這看起來簡單的在第一,但參數0
, 1
,和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.