src/Pure/General/sha1.scala
author wenzelm
Sat, 01 Jun 2019 11:29:59 +0200
changeset 70299 83774d669b51
parent 69393 ed0824ef337e
child 71775 291c46bf3000
permissions -rw-r--r--
Added tag Isabelle2019-RC4 for changeset ad2d84c42380
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38473
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/General/sha1.scala
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     3
41954
fb94df4505a0 explicit type SHA1.digest;
wenzelm
parents: 38473
diff changeset
     4
Digest strings according to SHA-1 (see RFC 3174).
38473
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     5
*/
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     6
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     7
package isabelle
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     8
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
     9
48409
0d2114eb412a more explicit java.io.{File => JFile};
wenzelm
parents: 48343
diff changeset
    10
import java.io.{File => JFile, FileInputStream}
38473
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    11
import java.security.MessageDigest
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    12
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    13
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    14
object SHA1
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    15
{
55802
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    16
  final class Digest private[SHA1](val rep: String)
41954
fb94df4505a0 explicit type SHA1.digest;
wenzelm
parents: 38473
diff changeset
    17
  {
55802
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    18
    override def hashCode: Int = rep.hashCode
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    19
    override def equals(that: Any): Boolean =
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    20
      that match {
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    21
        case other: Digest => rep == other.rep
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    22
        case _ => false
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    23
      }
41954
fb94df4505a0 explicit type SHA1.digest;
wenzelm
parents: 38473
diff changeset
    24
    override def toString: String = rep
fb94df4505a0 explicit type SHA1.digest;
wenzelm
parents: 38473
diff changeset
    25
  }
fb94df4505a0 explicit type SHA1.digest;
wenzelm
parents: 38473
diff changeset
    26
48343
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    27
  private def make_result(digest: MessageDigest): Digest =
38473
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    28
  {
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    29
    val result = new StringBuilder
48343
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    30
    for (b <- digest.digest()) {
38473
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    31
      val i = b.asInstanceOf[Int] & 0xFF
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    32
      if (i < 16) result += '0'
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    33
      result ++= Integer.toHexString(i)
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    34
    }
55802
f7ceebe2f1b5 prefer abstract datatype -- in accordance to ML version;
wenzelm
parents: 54440
diff changeset
    35
    new Digest(result.toString)
38473
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    36
  }
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    37
62702
e29f47e04180 tuned signature;
wenzelm
parents: 57638
diff changeset
    38
  def fake(rep: String): Digest = new Digest(rep)
e29f47e04180 tuned signature;
wenzelm
parents: 57638
diff changeset
    39
48409
0d2114eb412a more explicit java.io.{File => JFile};
wenzelm
parents: 48343
diff changeset
    40
  def digest(file: JFile): Digest =
48343
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    41
  {
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    42
    val digest = MessageDigest.getInstance("SHA")
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    43
69393
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    44
    using(new FileInputStream(file))(stream =>
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    45
    {
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    46
      val buf = new Array[Byte](65536)
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    47
      var m = 0
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    48
      try {
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    49
        do {
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    50
          m = stream.read(buf, 0, buf.length)
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    51
          if (m != -1) digest.update(buf, 0, m)
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    52
        } while (m != -1)
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    53
      }
ed0824ef337e static type for Library.using: avoid Java 11 warnings on "Illegal reflective access";
wenzelm
parents: 64370
diff changeset
    54
    })
48343
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    55
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    56
    make_result(digest)
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    57
  }
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    58
62704
478b49f0d726 proper SHA1 digest as annex to heap file: Poly/ML reads precise segment length;
wenzelm
parents: 62702
diff changeset
    59
  def digest(path: Path): Digest = digest(path.file)
478b49f0d726 proper SHA1 digest as annex to heap file: Poly/ML reads precise segment length;
wenzelm
parents: 62702
diff changeset
    60
48343
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    61
  def digest(bytes: Array[Byte]): Digest =
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    62
  {
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    63
    val digest = MessageDigest.getInstance("SHA")
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    64
    digest.update(bytes)
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    65
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    66
    make_result(digest)
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    67
  }
3060e6343953 more SHA1.digest operations;
wenzelm
parents: 45673
diff changeset
    68
54440
2c4940d2edf7 tuned signature;
wenzelm
parents: 50203
diff changeset
    69
  def digest(bytes: Bytes): Digest = bytes.sha1_digest
2c4940d2edf7 tuned signature;
wenzelm
parents: 50203
diff changeset
    70
  def digest(string: String): Digest = digest(Bytes(string))
57638
ed58e740a699 less authentic SHA1.digest: trust Scala side on blobs and avoid re-calculation via Foreign Language Interface, which might be a cause of problems;
wenzelm
parents: 55802
diff changeset
    71
62702
e29f47e04180 tuned signature;
wenzelm
parents: 57638
diff changeset
    72
  val digest_length: Int = digest("").rep.length
38473
bd96f2a5beb0 digesting strings according to SHA-1 -- Scala version;
wenzelm
parents:
diff changeset
    73
}