我试图表示在最短的字符串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!!")
  }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top