| author | wenzelm | 
| Thu, 01 Feb 2018 15:31:25 +0100 | |
| changeset 67561 | f0b11413f1c9 | 
| parent 64370 | 865b39487b5d | 
| child 69393 | ed0824ef337e | 
| permissions | -rw-r--r-- | 
| 38473 | 1  | 
/* Title: Pure/General/sha1.scala  | 
2  | 
Author: Makarius  | 
|
3  | 
||
| 41954 | 4  | 
Digest strings according to SHA-1 (see RFC 3174).  | 
| 38473 | 5  | 
*/  | 
6  | 
||
7  | 
package isabelle  | 
|
8  | 
||
9  | 
||
| 48409 | 10  | 
import java.io.{File => JFile, FileInputStream}
 | 
| 38473 | 11  | 
import java.security.MessageDigest  | 
12  | 
||
13  | 
||
14  | 
object SHA1  | 
|
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 | 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 | 24  | 
override def toString: String = rep  | 
25  | 
}  | 
|
26  | 
||
| 48343 | 27  | 
private def make_result(digest: MessageDigest): Digest =  | 
| 38473 | 28  | 
  {
 | 
29  | 
val result = new StringBuilder  | 
|
| 48343 | 30  | 
    for (b <- digest.digest()) {
 | 
| 38473 | 31  | 
val i = b.asInstanceOf[Int] & 0xFF  | 
32  | 
if (i < 16) result += '0'  | 
|
33  | 
result ++= Integer.toHexString(i)  | 
|
34  | 
}  | 
|
| 
55802
 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 
wenzelm 
parents: 
54440 
diff
changeset
 | 
35  | 
new Digest(result.toString)  | 
| 38473 | 36  | 
}  | 
37  | 
||
| 62702 | 38  | 
def fake(rep: String): Digest = new Digest(rep)  | 
39  | 
||
| 48409 | 40  | 
def digest(file: JFile): Digest =  | 
| 48343 | 41  | 
  {
 | 
42  | 
val stream = new FileInputStream(file)  | 
|
43  | 
    val digest = MessageDigest.getInstance("SHA")
 | 
|
44  | 
||
45  | 
val buf = new Array[Byte](65536)  | 
|
46  | 
var m = 0  | 
|
47  | 
    try {
 | 
|
48  | 
      do {
 | 
|
49  | 
m = stream.read(buf, 0, buf.length)  | 
|
50  | 
if (m != -1) digest.update(buf, 0, m)  | 
|
51  | 
} while (m != -1)  | 
|
52  | 
}  | 
|
53  | 
    finally { stream.close }
 | 
|
54  | 
||
55  | 
make_result(digest)  | 
|
56  | 
}  | 
|
57  | 
||
| 
62704
 
478b49f0d726
proper SHA1 digest as annex to heap file: Poly/ML reads precise segment length;
 
wenzelm 
parents: 
62702 
diff
changeset
 | 
58  | 
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
 | 
59  | 
|
| 48343 | 60  | 
def digest(bytes: Array[Byte]): Digest =  | 
61  | 
  {
 | 
|
62  | 
    val digest = MessageDigest.getInstance("SHA")
 | 
|
63  | 
digest.update(bytes)  | 
|
64  | 
||
65  | 
make_result(digest)  | 
|
66  | 
}  | 
|
67  | 
||
| 54440 | 68  | 
def digest(bytes: Bytes): Digest = bytes.sha1_digest  | 
69  | 
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
 | 
70  | 
|
| 62702 | 71  | 
  val digest_length: Int = digest("").rep.length
 | 
| 38473 | 72  | 
}  |