在使用一些代码库时,我试图理解一段代码,以便能够工作并自定义它,我能够理解几乎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,即列表中的第四个元素,如果我传递任何不是list getVoucherNumber方法一部分的值,则返回一个更高的值(大于列表计数)。
最让我困惑的是这两行
int voucherNumberPos = voucherCode.length() - 12;
String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6);根据我的理解,他们首先从客户提供的支票中移出前3位数字,但是他们没有使用字符串的其余部分,而是只使用字符串的特定部分。
有人能帮我理解这一点吗?
发布于 2014-10-08 19:02:24
似乎您继承了一些编写不当的代码的责任。我们都去过那里,所以我会尽力以这种精神回答。我不确定这个问题是关于这个网站的主题,但它似乎并不是禁止的帮助中心。为了停留在主题上,我将提出一些一般性的建议,而不局限于这个问题的高度本地化的细节。
myList.get(4)Java中的数组是基于零的,所以这就是123-MK93-E4D9-3A6T。你可能知道这一点,但从你的问题上看不清楚你是怎么做的。
initial-alphabet : M9W6K3TENDGSFAL4我假设这就是调用getAlphabet in 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设置为一个6个字符的长字符串,从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;
}"found“后面的右大括号被注释掉,所以您发布的代码实际上是不完整的。我假设还有一两行
return pos;
}因此,基本思想是M变成0,9变成1,等等,通过调用indexOf。但是,如果这个方法看到一个字符不在提供的字母表中,比如连字符,它使用所谓的offset来计算一个默认值(在本例中是14,如果我在我的脑海中做了数学运算),并将其返回为十六进制咬取值。
最终的结果是,您返回的数字范围为0(包括)到2^24 (排他性)。但是,在这样一个数字应该具有的2^24个可能值中,只有2^20个不同的值将被返回。因此,从一个看上去像12位基数的代金券代码--32,它有一个天文数字的值,在每个客户前缀中,你被限制在略超过一百万个不同的凭证号码。
一般建议:
https://stackoverflow.com/questions/26268530
复制相似问题