質問

MD5ハッシュの結果を可能な限り短い文字列で表現しようとしています。それを16進文字列に変えてGからZを無駄にするだけでは無駄に思えます。

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

問題は、 BigInt が任意のバイト配列で構築できるかどうかわからないことであり、テストでは証明できません(少なくともタイムリーではありません!)。 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)
  }

}

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

編集:これを証明するために必要なテストはここに文書化されています: 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