在使用一些代码库时,我试图理解一段代码,以便可以工作和自定义它,我能够理解几乎90%的代码流.这是整体流程
我对用于确定所提供的代码是否有效的逻辑感到震惊,这里是那段代码,我生成6个代码作为样本,在这种情况下,生成并存储在缓存中的字母数字代码是
initial-alphabet : M9W6K3TENDGSFAL4
Run Code Online (Sandbox Code Playgroud)
基于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;
}
Run Code Online (Sandbox Code Playgroud)
这是试图验证代码的代码
int voucherNumber = getVoucherNumber(kyList.get(4));
Run Code Online (Sandbox Code Playgroud)
在这种情况下,值voucherNumber
是4
来自列表的第四个元素,如果我传递任何不属于list getVoucherNumber
方法的值,则返回更高的值(大于列表计数).
困扰我的主要原因之一是这两行
int voucherNumberPos = voucherCode.length() - 12;
String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6);
Run Code Online (Sandbox Code Playgroud)
根据我的理解,他们首先从支票中移出前三位数,这是客户提供的,但他们又没有使用其余的字符串,只是字符串的特定部分.
任何人都可以帮助我理解这一点
看来你已经继承了一些写得不好的代码的责任.我们都去过那里,所以我会试着以这种精神回答.我不是肯定这个问题是关于这个网站的主题,但它似乎并没有被帮助中心禁止.为了保持主题,我将以一些不仅限于问题的高度本地化细节的一般建议结束.
myList.get(4)
Run Code Online (Sandbox Code Playgroud)
Java中的数组是从零开始的,所以就是这样123-MK93-E4D9-3A6T
.你可能知道这一点,但你的问题并不清楚.
initial-alphabet : M9W6K3TENDGSFAL4
Run Code Online (Sandbox Code Playgroud)
我想这是什么通过调用返回到getAlphabet
在getIntFromHexNibble
.因此,代码中的字母数字字符应为十六进制,但对数字使用非标准的16个字符集.
protected int getVoucherNumber(String voucherCode){
Run Code Online (Sandbox Code Playgroud)
忽略连字符和客户提供的前三位数字,代码为"MK93E4D93A6T".十二进制数字编码48位,但int
Java中只有32位长,因此代码已经被破坏.无论它做什么,它都不会返回凭证代码所代表的凭证号码.
int voucherNumberPos = voucherCode.length() - 12;
String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6);
Run Code Online (Sandbox Code Playgroud)
这是将voucherNumberHex设置为六个字符长的字符串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);
Run Code Online (Sandbox Code Playgroud)
这看起来很简单,但参数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;
}
Run Code Online (Sandbox Code Playgroud)
"found"之后的右大括号已被注释掉,因此您发布的代码实际上是不完整的.我将假设还有另外一两行阅读
return pos;
}
Run Code Online (Sandbox Code Playgroud)
所以基本的想法是通过调用M
变为0,9
变为1,依此类推indexOf
.但是如果这个方法看到的字符不在提供的字母表中,比如连字符,它会使用所谓offset
的计算默认值(在这种情况下为14,如果我已经在我头脑中完成了数学计算),并返回作为十六进制半字节值.
最终结果是您返回0(含)到2 ^ 24(不包括)范围内的数字.但是在这个数字应该具有的2 ^ 24个可能值中,将仅返回2 ^ 20个不同的值.因此,从看起来像基数为32的十二位数的凭证代码(其具有天文数字的值),您在每个客户前缀内限制为略多于一百万个不同的凭证数.
一般建议:
归档时间: |
|
查看次数: |
134 次 |
最近记录: |