| author | matichuk <daniel.matichuk@nicta.com.au> | 
| Mon, 30 May 2016 16:11:53 +1000 | |
| changeset 63185 | 08369e33c185 | 
| parent 62704 | 478b49f0d726 | 
| child 64370 | 865b39487b5d | 
| permissions | -rw-r--r-- | 
| 38473 | 1 | /* Title: Pure/General/sha1.scala | 
| 45673 
cd41e3903fbf
separate compilation of PIDE vs. Pure sources, which enables independent Scala library;
 wenzelm parents: 
45667diff
changeset | 2 | Module: PIDE | 
| 38473 | 3 | Author: Makarius | 
| 4 | ||
| 41954 | 5 | Digest strings according to SHA-1 (see RFC 3174). | 
| 38473 | 6 | */ | 
| 7 | ||
| 8 | package isabelle | |
| 9 | ||
| 10 | ||
| 48409 | 11 | import java.io.{File => JFile, FileInputStream}
 | 
| 38473 | 12 | import java.security.MessageDigest | 
| 13 | ||
| 14 | ||
| 15 | object SHA1 | |
| 16 | {
 | |
| 55802 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 17 | final class Digest private[SHA1](val rep: String) | 
| 41954 | 18 |   {
 | 
| 55802 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 19 | override def hashCode: Int = rep.hashCode | 
| 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 20 | override def equals(that: Any): Boolean = | 
| 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 21 |       that match {
 | 
| 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 22 | case other: Digest => rep == other.rep | 
| 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 23 | case _ => false | 
| 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 24 | } | 
| 41954 | 25 | override def toString: String = rep | 
| 26 | } | |
| 27 | ||
| 48343 | 28 | private def make_result(digest: MessageDigest): Digest = | 
| 38473 | 29 |   {
 | 
| 30 | val result = new StringBuilder | |
| 48343 | 31 |     for (b <- digest.digest()) {
 | 
| 38473 | 32 | val i = b.asInstanceOf[Int] & 0xFF | 
| 33 | if (i < 16) result += '0' | |
| 34 | result ++= Integer.toHexString(i) | |
| 35 | } | |
| 55802 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 wenzelm parents: 
54440diff
changeset | 36 | new Digest(result.toString) | 
| 38473 | 37 | } | 
| 38 | ||
| 62702 | 39 | def fake(rep: String): Digest = new Digest(rep) | 
| 40 | ||
| 48409 | 41 | def digest(file: JFile): Digest = | 
| 48343 | 42 |   {
 | 
| 43 | val stream = new FileInputStream(file) | |
| 44 |     val digest = MessageDigest.getInstance("SHA")
 | |
| 45 | ||
| 46 | val buf = new Array[Byte](65536) | |
| 47 | var m = 0 | |
| 48 |     try {
 | |
| 49 |       do {
 | |
| 50 | m = stream.read(buf, 0, buf.length) | |
| 51 | if (m != -1) digest.update(buf, 0, m) | |
| 52 | } while (m != -1) | |
| 53 | } | |
| 54 |     finally { stream.close }
 | |
| 55 | ||
| 56 | make_result(digest) | |
| 57 | } | |
| 58 | ||
| 62704 
478b49f0d726
proper SHA1 digest as annex to heap file: Poly/ML reads precise segment length;
 wenzelm parents: 
62702diff
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: 
62702diff
changeset | 60 | |
| 48343 | 61 | def digest(bytes: Array[Byte]): Digest = | 
| 62 |   {
 | |
| 63 |     val digest = MessageDigest.getInstance("SHA")
 | |
| 64 | digest.update(bytes) | |
| 65 | ||
| 66 | make_result(digest) | |
| 67 | } | |
| 68 | ||
| 54440 | 69 | def digest(bytes: Bytes): Digest = bytes.sha1_digest | 
| 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: 
55802diff
changeset | 71 | |
| 62702 | 72 |   val digest_length: Int = digest("").rep.length
 | 
| 38473 | 73 | } |