首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解Java代码

理解Java代码
EN

Stack Overflow用户
提问于 2014-10-08 16:42:55
回答 1查看 180关注 0票数 0

在使用一些代码库时,我试图理解一段代码,以便能够工作并自定义它,我能够理解几乎90%的代码流。以下是整个流程

  1. 代码用于生成15位数字代码(字母数字),客户提供前3位数字。
  2. 最初,代码是生成16位字母数字数字,并将其存储在缓存中。
  3. 客户可以通过指定数量生成任意数量的代码。
  4. 所有客户生成的代码都是从16位数字(第2点)生成的。所有生成的代码都有来自该16位字母数字的数字/字母。
  5. 当有人试图使用这些代码时,系统试图验证所提供的代码是否有效。

我对用于确定所提供的代码是否有效的逻辑感到震惊,这里是一段代码,我正在生成6段代码作为一个示例,在这种情况下,生成的字母数字代码并存储在缓存中

代码语言:javascript
复制
 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]

代码语言:javascript
复制
 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;
 }

下面是试图验证代码的代码

代码语言:javascript
复制
 int voucherNumber = getVoucherNumber(kyList.get(4));

在这种情况下,voucherNumber的值是4,即列表中的第四个元素,如果我传递任何不是list getVoucherNumber方法一部分的值,则返回一个更高的值(大于列表计数)。

最让我困惑的是这两行

代码语言:javascript
复制
int voucherNumberPos = voucherCode.length() - 12;
String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6);

根据我的理解,他们首先从客户提供的支票中移出前3位数字,但是他们没有使用字符串的其余部分,而是只使用字符串的特定部分。

有人能帮我理解这一点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-08 19:02:24

似乎您继承了一些编写不当的代码的责任。我们都去过那里,所以我会尽力以这种精神回答。我不确定这个问题是关于这个网站的主题,但它似乎并不是禁止的帮助中心。为了停留在主题上,我将提出一些一般性的建议,而不局限于这个问题的高度本地化的细节。

代码语言:javascript
复制
myList.get(4)

Java中的数组是基于零的,所以这就是123-MK93-E4D9-3A6T。你可能知道这一点,但从你的问题上看不清楚你是怎么做的。

代码语言:javascript
复制
initial-alphabet : M9W6K3TENDGSFAL4

我假设这就是调用getAlphabet in getIntFromHexNibble返回的内容。因此,代码中的字母数字字符应该是十六进制字符,但是对于数字使用一组非标准的16个字符。

代码语言:javascript
复制
protected  int getVoucherNumber(String voucherCode){

忽略连字符和客户提供的前三位数,代码是'MK93E4D93A6T‘。12位十六进制数字编码48位,但Java中的int只有32位长,因此代码已经中断。不管它做什么,它都不会返回凭单代码表示的凭单编号。

代码语言:javascript
复制
int voucherNumberPos = voucherCode.length() - 12;
String voucherNumberHex = voucherCode.substring(voucherNumberPos, voucherNumberPos + 6);

这是将voucherNumberHex设置为一个6个字符的长字符串,从voucherCode的末尾开始,在本例中是93-E4D。在第一次编写这段代码时,作者似乎并没有期望调用者包括连字符。即使如此,其意图似乎是忽略一半的代金券代码。

代码语言:javascript
复制
int firstByte = getIntFromHexByte(voucherNumberHex.substring(0, 2), 0);
int secondByte = getIntFromHexByte(voucherNumberHex.substring(2, 4), 1);
int thirdByte = getIntFromHexByte(voucherNumberHex.substring(4, 6), 7);

这在一开始看起来很简单,但是参数017根本就不是抵消的,尽管参数的名称是参数。它试图将每一对十六进制数字转换成一个字节,如果没有连字符,这将是足够明智的。现在是有趣的部分:

代码语言:javascript
复制
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“后面的右大括号被注释掉,所以您发布的代码实际上是不完整的。我假设还有一两行

代码语言:javascript
复制
    return pos;
}

因此,基本思想是M变成0,9变成1,等等,通过调用indexOf。但是,如果这个方法看到一个字符不在提供的字母表中,比如连字符,它使用所谓的offset来计算一个默认值(在本例中是14,如果我在我的脑海中做了数学运算),并将其返回为十六进制咬取值。

最终的结果是,您返回的数字范围为0(包括)到2^24 (排他性)。但是,在这样一个数字应该具有的2^24个可能值中,只有2^20个不同的值将被返回。因此,从一个看上去像12位基数的代金券代码--32,它有一个天文数字的值,在每个客户前缀中,你被限制在略超过一百万个不同的凭证号码。

一般建议:

  • 使用同行评审来防止这样的代码进入生产。
  • 使用单元测试来证明代码实现了函数名所表示的功能。
  • 如果输入不是您所期望的,请使用异常提前失败。
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26268530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档