\( \def\vector#1{\boldsymbol{#1}} \)

ハッシュ関数

Takami Torao
  • このエントリーをはてなブックマークに追加
アルゴリズム 算出時間 (1GB) ハッシュサイズ
CRC32 804.00msec 4B
MD2 86691.11msec 16B
MD5 2635.62msec 16B
SHA 3685.01msec 20B
SHA-224 5395.42msec 28B
SHA-256 5381.95msec 32B
SHA-384 3746.54msec 48B
SHA-512 3737.19msec 64B
import java.io._
import java.nio.ByteBuffer
import java.security._
import java.util.zip.CRC32

import scala.annotation.tailrec
import scala.collection.JavaConverters._

// dd if=/dev/zero of=empty.dat bs=1m count=1024
val file = new File("empty.dat")
file.deleteOnExit()
val buffer = new Array[Byte](8 * 1024)
assert(file.length() == 1024 * 1024 * 1024)

def performance(algorithm: String, update: (Array[Byte], Int, Int) => Unit, get: () => Array[Byte]): Unit = {
  val in = new FileInputStream(file)

  @tailrec
  def _read(): Unit = {
    val len = in.read(buffer)
    if (len > 0) {
      update(buffer, 0, len)
      _read()
    }
  }

  System.out.print(s"$algorithm: ")
  System.out.flush()
  val start = System.nanoTime()
  _read()
  val nanosec = System.nanoTime() - start
  in.close()
  val digest = get()
  val hex = digest.map { b => f"$b%02x" }.mkString
  System.out.println(f"${nanosec / 1000.0 / 1000.0}%,.2fmsec: $hex%s (${digest.length}%,dB)")
}

locally {
  val crc32 = new CRC32()
  performance("CRC32", (buffer, offset, length) => crc32.update(buffer, offset, length), {() =>
    val hash = crc32.getValue
    ByteBuffer.allocate(java.lang.Long.BYTES).putLong(hash).array()
  })
}

Security.getAlgorithms("MessageDigest").asScala.toList.sorted.foreach { algorithm =>
  val md = MessageDigest.getInstance(algorithm)
  performance(algorithm, (buffer, offset, length) => md.update(buffer, offset, length), () => md.digest())
}

file.delete()
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

参照