| author | wenzelm | 
| Sun, 02 Oct 2016 14:07:43 +0200 | |
| changeset 63992 | 3aa9837d05c7 | 
| 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: 
45667 
diff
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: 
54440 
diff
changeset
 | 
17  | 
final class Digest private[SHA1](val rep: String)  | 
| 41954 | 18  | 
  {
 | 
| 
55802
 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 
wenzelm 
parents: 
54440 
diff
changeset
 | 
19  | 
override def hashCode: Int = rep.hashCode  | 
| 
 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 
wenzelm 
parents: 
54440 
diff
changeset
 | 
20  | 
override def equals(that: Any): Boolean =  | 
| 
 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 
wenzelm 
parents: 
54440 
diff
changeset
 | 
21  | 
      that match {
 | 
| 
 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 
wenzelm 
parents: 
54440 
diff
changeset
 | 
22  | 
case other: Digest => rep == other.rep  | 
| 
 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 
wenzelm 
parents: 
54440 
diff
changeset
 | 
23  | 
case _ => false  | 
| 
 
f7ceebe2f1b5
prefer abstract datatype -- in accordance to ML version;
 
wenzelm 
parents: 
54440 
diff
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: 
54440 
diff
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: 
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 | 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: 
55802 
diff
changeset
 | 
71  | 
|
| 62702 | 72  | 
  val digest_length: Int = digest("").rep.length
 | 
| 38473 | 73  | 
}  |