Repository navigation
Expand file tree
/
Copy path_sha256.cs
More file actions
170 lines (139 loc) · 5.2 KB
/
Copy path_sha256.cs
File metadata and controls
170 lines (139 loc) · 5.2 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* [email protected]. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
*
* ***************************************************************************/
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Scripting.Runtime;
using IronPython.Runtime;
using IronPython.Runtime.Operations;
//!!! This is pretty inefficient. We should probably use hasher.TransformBlock instead of
//!!! hanging onto all of the bytes.
//!!! Also, we could probably make a generic version of this that could then be specialized
//!!! for both md5 and sha.
[assembly: PythonModule("_sha256", typeof(IronPython.Modules.PythonSha256))]
namespace IronPython.Modules {
[Documentation("SHA256 hash algorithm")]
public static class PythonSha256 {
[ThreadStatic]
private static SHA256 _hasher256;
private const int blockSize = 64;
public const string __doc__ = "SHA256 hash algorithm";
private static SHA256 GetHasher() {
if (_hasher256 == null) {
_hasher256 = new SHA256Managed();
}
return _hasher256;
}
public static Sha256Object sha256(object data) {
return new Sha256Object(data);
}
public static Sha256Object sha256(Bytes data) {
return new Sha256Object((IList<byte>)data);
}
public static Sha256Object sha256(PythonBuffer data) {
return new Sha256Object((IList<byte>)data);
}
public static Sha256Object sha256(ByteArray data) {
return new Sha256Object((IList<byte>)data);
}
public static Sha256Object sha256() {
return new Sha256Object();
}
public static Sha256Object sha224(object data) {
throw new NotImplementedException();
}
public static Sha256Object sha224() {
throw new NotImplementedException();
}
[PythonHidden]
public sealed class Sha256Object : HashBase
#if FEATURE_ICLONEABLE
, ICloneable
#endif
{
internal Sha256Object() : this(new byte[0]) { }
internal Sha256Object(object initialData) {
_bytes = new byte[0];
update(initialData);
}
internal Sha256Object(IList<byte> initialBytes) {
_bytes = new byte[0];
update(initialBytes);
}
internal override HashAlgorithm Hasher {
get {
return GetHasher();
}
}
[Documentation("copy() -> object (copy of this object)")]
public Sha256Object copy() {
return new Sha256Object(_bytes);
}
#if FEATURE_ICLONEABLE
object ICloneable.Clone() {
return copy();
}
#endif
public const int block_size = 64;
public const int digest_size = 32;
public const int digestsize = 32;
public const string name = "SHA256";
}
}
public class HashBase {
internal byte[] _bytes;
private byte[] _hash;
internal HashBase() {
}
internal virtual HashAlgorithm Hasher {
get {
throw new NotImplementedException();
}
}
public void update(Bytes newBytes) {
update((IList<byte>)newBytes);
}
public void update(ByteArray newBytes) {
update((IList<byte>)newBytes);
}
internal void update(IList<byte> newBytes) {
byte[] updatedBytes = new byte[_bytes.Length + newBytes.Count];
Array.Copy(_bytes, updatedBytes, _bytes.Length);
newBytes.CopyTo(updatedBytes, _bytes.Length);
_bytes = updatedBytes;
_hash = Hasher.ComputeHash(_bytes);
}
[Documentation("update(string) -> None (update digest with string data)")]
public void update(object newData) {
update(Converter.ConvertToString(newData).MakeByteArray());
}
public void update(PythonBuffer buffer) {
update((IList<byte>)buffer);
}
[Documentation("digest() -> int (current digest value)")]
public string digest() {
return _hash.MakeString();
}
[Documentation("hexdigest() -> string (current digest as hex digits)")]
public string hexdigest() {
StringBuilder result = new StringBuilder(2 * _hash.Length);
for (int i = 0; i < _hash.Length; i++) {
result.Append(_hash[i].ToString("x2"));
}
return result.ToString();
}
}
}