1

MD5 ハッシュの結果を可能な限り短い文字列で表現しようとしています。単純に 16 進文字列にして、G から Z までを無駄にするのはもったいないようです。

私が持っていた 1 つのアイデアは、入力の MD5 ハッシュをバイト配列として取得し、それを使用して を構築するBigIntことです。次に、 を呼び出しtoString(36)て、数値を文字列の base-36 として取得-?[0-9a-z]*できます ( 、数値は正または負の値になります)。わたしにはできる。

問題は、任意のバイト配列で a を構築できるかどうか確信が持てBigIntず、テストでそれを証明できないことです (少なくともタイムリーな方法ではありません!)。BigInt は任意のサイズになる可能性があることを理解しているため、そう思います。この方法は、考えられるすべての出力で機能することが確実にわかるまで使用できません。それで、それがすべての入力に対して機能するかどうか(またはバイト配列を簡単に変換してbase 36で表現できるようにする方法)を教えてください。

明確化: 私は実装を持っています。ドメイン全体の動作について質問しています (つまり、00000000000000000000000000000 から FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)

4

2 に答える 2

3

上記のフィードバックに基づいて、次の実装は任意のバイト配列を確実にエンコード/デコードします。

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)
  }

}

バイト配列の 2 の補数を取ることによる副作用を避けるために、配列の先頭に余分な 0x01 バイトを追加していることに注意してください。

編集: これを証明するために必要なテストは、ここに文書化されています: http://cleverlytitled.blogspot.com/2009/10/scalacheck.html

于 2009-10-30T03:55:45.917 に答える
0

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!!")
  }
于 2009-10-29T18:10:32.787 に答える