我需要生成一个3字节的代码(如A502F1)。我得到了一个标准:
第一个字节是(serialCodeNumber/(256*256))&0xFF
第二个是(serialCodeNumber/256)&0xFF
3th是(serialCodeNumber)&0xFF
serialCodeNumber是一个序列1-0xFFF
这是什么意思!?
我会这样生成:
String codeNum = new BigInteger(256, random).toString(16).toUpperCase().substring(0, 6);
但是,按照要求,正确的做法是什么?
我不太确定serialCodeNumber
是什么意思,因为如果它后来被65025整除,它必须是一个比0xFFF(即4095)大得多的数字才能有合理的意义。
但让我们来看看这些条件,一旦你习惯了按位AND运算符,它们都会有意义。关于它是如何工作的,这里有一本很好的读物,但在我看来,这个问题的核心是Markus Jarderot的这句话:
结果是在两个数字中都打开的位。
因为在你的条件下,你有& 0xFF
和0xFF是255,或者在二进制中,它是11111111,前八位都打开了。这是一个只检索任何数字的前八位的巧妙技巧。众所周知,8位组成一个字节。(你现在开始看到这一切的进展了吗?)
至于& 0xFF
之前的条件,有些人可能会将其识别为隐藏在除法后面的移位操作。
(serialCodeNumber / (256*256))
相当于(serialCodeNumber >> 16)
和
(serialCodeNumber / 256)
相当于(serialCodeNumber >> 8)
但在这种情况下,这并不那么重要。
因此,第一个条件取serialCodeNumber
除以65025(256*256),然后查看最右边的8个比特,忽略任何其他比特,从这8个比特中构建一个字节。
在Java中,您几乎可以直接编写条件:
byte myFirstByte = (byte) ((serialCodeNumber / (256*256)) & 0xFF);
其他条件没有太大区别:
byte mySecondByte = (byte) ((serialCodeNumber / (256)) & 0xFF);
和
byte myThirdByte = (byte) ((serialCodeNumber) & 0xFF);
一旦您拥有了所有三个字节,我假设您需要将它们转换为十六进制字符串。所以我将它们添加到一个字节数组中。
byte[] myArray = {myFirstByte,mySecondByte,myThirdByte};
并从这个问题中借用了一些关于如何将字节数组转换为十六进制字符串的方法。
String codeNum = bytesToHex(myArray);
结果看起来像这样:
F03DD7
编辑:
由于您必须生成一个值最多为6字节的序列号,因此我建议使用long
号。
一个6字节的数字将在1到281474976710655之间,所以您可能需要随机生成一个。
首先实例化一个Random
对象,您将能够从以下位置轮询数字:
Random random = new Random();
一旦你有了它,从中轮询一个long
,范围为1到281474976710655。
对于这个问题,你可以借用KennyTM的答案。
所以你可以生成这样的数字:
long serialCodeNumber = nextLong(random, 281474976710655L)+1L;
我们在末尾添加+1L
,因为我们希望它包括最后一个数字,并从1开始,而不是从0开始。
如果您需要显示serialCodeNumber的十六进制字符串,您可以调用:
String serialHex = Long.toHexString(serialCodeNumber);
但是,请确保根据字符串的长度在左侧添加任何额外的"0",使其为6字节=12个字符长。