我可以构建任何字节数组(斯卡拉)一个BIGINT?
-
10-07-2019 - |
题
我试图表示在最短的字符串MD5哈希的结果。这似乎是一种浪费,只是把它变成一个十六进制字符串,让到Z g进浪费。
一个想法我有越来越我作为字节数组输入的MD5哈希和构建BigInt
它。然后我可以调用toString(36)
,并获得数作为一个字符串碱-36(-?[0-9a-z]*
,数目可以是正或负)。它为我工作。
问题是,我不知道一个<=>可以与任何字节阵列来构造,并且我不能与测试证明它(至少不是及时的方式!)。我认为是这样,因为我明白,一个BIGINT可以是任意大小的。直到我肯定知道它会为所有可能的输出工作,我不能用这种方法。所以,任何人都可以告诉我是否会针对所有输入工作(或如何很容易地转换为字节数组,因此可以在基体36来表示)。
<强>澄清强>:我已实施,我问的行为在整个域(即00000000000000000000000000000000至FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
解决方案
在上述的反馈大厦,下面的实现将可靠地编码/解码的任意字节数组:
package blevins.example
object BigIntEncoder {
val radix = 36
implicit def byteArrayToString(ba: Array[Byte]): String = {
new java.math.BigInteger(addByte(ba)).toString(radix)
}
implicit def stringToByteArray(s: String): Array[Byte] = {
stripByte(new java.math.BigInteger(s, radix).toByteArray)
}
def addByte(ba: Array[Byte]): Array[Byte] = {
val h = new Array[Byte](1)
h(0) = 0x01
h ++ ba
}
def stripByte(ba: Array[Byte]): Array[Byte] = {
ba.slice(1,ba.size)
}
}
请注意,我们正在增加一个额外的0×01字节阵列的头,以避免从取字节数组的双补任何副作用。
编辑:参与证明了这一点,测试记录在这里: HTTP:// cleverlytitled.blogspot.com/2009/10/scalacheck.html
其他提示
岂不Base64编码比Base36短?你可以找到很多身边的实现。
但是,实际上回答这个问题:
// Make a big randomly-filled byte array
val random = scala.util.Random
val arraySize = 8543
val bytes: Array[Byte] = new Array[Byte](arraySize) // make some big array
random.nextBytes(bytes) // fill it randomly
// Make a BigInt out of it and the corresponding base36 string representation
val bi: BigInt = new BigInt(new java.math.BigInteger(bytes))
val strRep: String = bi.toString(36)
// Make a new BigInt out of the string rep. Does it match?
val bi2: BigInt = new BigInt(new java.math.BigInteger(strRep, 36))
if (bi == bi2) {
println("yippee!!")
}
// Make a new byte array out of the BigInt. Does it match the original array?
val bytes2: Array[Byte] = bi2.toByteArray
if (bytes deepEquals bytes2) {
println("yippee again!!")
}
不隶属于 StackOverflow