forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path_hashlib.cs
More file actions
106 lines (87 loc) · 3.34 KB
/
_hashlib.cs
File metadata and controls
106 lines (87 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Scripting.Runtime;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
//[assembly: PythonModule("_hashlib", typeof(IronPython.Modules.PythonHashlib))]
namespace IronPython.Modules {
[PythonHidden]
public abstract class HashBase<T>
#if FEATURE_ICLONEABLE
: ICloneable
#endif
where T : HashAlgorithm {
protected T _hasher;
private static MethodInfo _memberwiseClone;
private static readonly byte[] _empty = new byte[0];
public readonly string name;
public readonly int block_size;
public readonly int digest_size;
public readonly int digestsize;
internal HashBase(string name, int blocksize, int digestsize) {
this.name = name;
this.block_size = blocksize;
this.digest_size = this.digestsize = digestsize;
CreateHasher();
}
protected abstract void CreateHasher();
[Documentation("update(string) -> None (update digest with string data)")]
public void update([BytesConversion]IList<byte> newBytes) {
byte[] bytes = newBytes.ToArray();
lock (_hasher) {
_hasher.TransformBlock(bytes, 0, bytes.Length, bytes, 0);
}
}
[Documentation("digest() -> int (current digest value)")]
public Bytes digest() {
T copy = CloneHasher();
copy.TransformFinalBlock(_empty, 0, 0);
return Bytes.Make(copy.Hash);
}
[Documentation("hexdigest() -> string (current digest as hex digits)")]
public string hexdigest() {
T copy = CloneHasher();
copy.TransformFinalBlock(_empty, 0, 0);
StringBuilder result = new StringBuilder(2 * copy.Hash.Length);
for (int i = 0; i < copy.Hash.Length; i++) {
result.Append(copy.Hash[i].ToString("x2"));
}
return result.ToString();
}
public abstract HashBase<T> copy();
#if FEATURE_ICLONEABLE
object ICloneable.Clone() {
return copy();
}
#endif
protected T CloneHasher() {
T clone = default(T);
if (_memberwiseClone == null) {
_memberwiseClone = _hasher.GetType().GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
}
if (_memberwiseClone != null) {
lock (_hasher) {
clone = (T)_memberwiseClone.Invoke(_hasher, new object[0]);
}
}
FieldInfo[] fields = _hasher.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if(fields != null) {
foreach(FieldInfo field in fields) {
if(field.FieldType.IsArray) {
lock (_hasher) {
Array orig = field.GetValue(_hasher) as Array;
if (orig != null) {
field.SetValue(clone, orig.Clone());
}
}
}
}
}
return clone;
}
}
}