Skip to content

Commit 92b1f41

Browse files
committed
Merge branch 'master' into feature/1.0
2 parents 8ea7198 + 89586ac commit 92b1f41

File tree

8 files changed

+223
-47
lines changed

8 files changed

+223
-47
lines changed

CatLib.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26430.16
4+
VisualStudioVersion = 15.0.26430.13
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatLib", "projects\CatLib\CatLib.csproj", "{BBB2DAE2-638B-4419-9591-3CECCA312E4E}"
77
EndProject

projects/CatLib.API/Hashing/Checksums.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,33 @@ namespace CatLib.API.Hashing
1414
/// <summary>
1515
/// 使用的校验方法
1616
/// </summary>
17-
public enum Checksums
17+
public class Checksums : Enum
1818
{
1919
/// <summary>
2020
/// Adler32
2121
/// </summary>
22-
Adler32,
22+
public static readonly Checksums Adler32 = new Checksums("Adler32");
2323

2424
/// <summary>
2525
/// Crc32
2626
/// </summary>
27-
Crc32,
27+
public static readonly Checksums Crc32 = new Checksums("Crc32");
28+
29+
/// <summary>
30+
/// 哈希算法类型
31+
/// </summary>
32+
/// <param name="name">哈希算法名字</param>
33+
protected Checksums(string name) : base(name)
34+
{
35+
}
36+
37+
/// <summary>
38+
/// 字符串转Checksums
39+
/// </summary>
40+
/// <param name="type">类型</param>
41+
public static implicit operator Checksums(string type)
42+
{
43+
return new Checksums(type);
44+
}
2845
}
2946
}

projects/CatLib.API/Hashing/Hashes.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,33 @@ namespace CatLib.API.Hashing
1414
/// <summary>
1515
/// 哈希算法
1616
/// </summary>
17-
public enum Hashes
17+
public class Hashes : Enum
1818
{
1919
/// <summary>
2020
/// DJB Hash
2121
/// </summary>
22-
Djb,
22+
public static readonly Hashes Djb = new Hashes("Djb");
2323

2424
/// <summary>
2525
/// Murmur Hash
2626
/// </summary>
27-
MurmurHash
27+
public static readonly Hashes MurmurHash = new Hashes("MurmurHash");
28+
29+
/// <summary>
30+
/// 哈希算法类型
31+
/// </summary>
32+
/// <param name="name">哈希算法名字</param>
33+
protected Hashes(string name) : base(name)
34+
{
35+
}
36+
37+
/// <summary>
38+
/// 字符串转Hashes
39+
/// </summary>
40+
/// <param name="type">类型</param>
41+
public static implicit operator Hashes(string type)
42+
{
43+
return new Hashes(type);
44+
}
2845
}
2946
}

projects/CatLib.API/Hashing/IHashing.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,20 @@ namespace CatLib.API.Hashing
1818
/// </summary>
1919
public interface IHashing
2020
{
21+
/// <summary>
22+
/// 计算校验和
23+
/// </summary>
24+
/// <param name="buffer">字节数组</param>
25+
/// <returns>校验和</returns>
26+
long Checksum(byte[] buffer);
27+
2128
/// <summary>
2229
/// 计算校验和
2330
/// </summary>
2431
/// <param name="buffer">字节数组</param>
2532
/// <param name="checksum">使用校验类类型</param>
2633
/// <returns>校验和</returns>
27-
long Checksum(byte[] buffer , Checksums checksum = Checksums.Crc32);
34+
long Checksum(byte[] buffer, Checksums checksum);
2835

2936
/// <summary>
3037
/// 对输入值进行加密性Hash
@@ -42,13 +49,20 @@ public interface IHashing
4249
/// <returns>是否匹配</returns>
4350
bool CheckPassword(string input, string hash);
4451

52+
/// <summary>
53+
/// 对输入值进行非加密哈希
54+
/// </summary>
55+
/// <param name="input">输入值</param>
56+
/// <returns>哈希值</returns>
57+
uint HashString(string input);
58+
4559
/// <summary>
4660
/// 对输入值进行非加密哈希
4761
/// </summary>
4862
/// <param name="input">输入值</param>
4963
/// <param name="hash">使用的哈希算法</param>
5064
/// <returns>哈希值</returns>
51-
uint HashString(string input, Hashes hash = Hashes.MurmurHash);
65+
uint HashString(string input, Hashes hash);
5266

5367
/// <summary>
5468
/// 对输入值进行非加密哈希
@@ -57,14 +71,21 @@ public interface IHashing
5771
/// <param name="encoding">编码</param>
5872
/// <param name="hash">使用的哈希算法</param>
5973
/// <returns>哈希值</returns>
60-
uint HashString(string input, Encoding encoding, Hashes hash = Hashes.MurmurHash);
74+
uint HashString(string input, Encoding encoding, Hashes hash);
75+
76+
/// <summary>
77+
/// 对输入值进行非加密哈希
78+
/// </summary>
79+
/// <param name="input">输入值</param>
80+
/// <returns>哈希值</returns>
81+
uint HashByte(byte[] input);
6182

6283
/// <summary>
6384
/// 对输入值进行非加密哈希
6485
/// </summary>
6586
/// <param name="input">输入值</param>
6687
/// <param name="hash">使用的哈希算法</param>
6788
/// <returns>哈希值</returns>
68-
uint HashByte(byte[] input, Hashes hash = Hashes.MurmurHash);
89+
uint HashByte(byte[] input, Hashes hash);
6990
}
7091
}

projects/CatLib.Tests/Hashing/HashingProviderTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,18 @@ public void TestCrc64()
4343
{
4444
var app = MakeEnv();
4545
var hash = app.Make<IHashing>();
46+
var code0 = hash.Checksum(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
4647
var code = hash.Checksum(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, Checksums.Crc32);
4748
var code2 = hash.Checksum(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, Checksums.Crc32);
4849
var code3 = hash.Checksum(new byte[] { 0, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, Checksums.Crc32);
4950
var code4 = hash.Checksum(System.Text.Encoding.Default.GetBytes("123"), Checksums.Crc32);
51+
var code5 = hash.Checksum(System.Text.Encoding.Default.GetBytes("123"));
5052

53+
Assert.AreEqual(code, code0);
5154
Assert.AreEqual(code , code2);
5255
Assert.AreNotEqual(code2 , code3);
5356
Assert.AreEqual(2286445522, code4);
57+
Assert.AreEqual(2286445522, code5);
5458
}
5559

5660
[TestMethod]
@@ -102,12 +106,16 @@ public void TestMurmurHash()
102106
var app = MakeEnv();
103107
var hash = app.Make<IHashing>();
104108

109+
var hash0 = hash.HashString("helloworld");
105110
var hash1 = hash.HashString("helloworld", Hashes.MurmurHash);
106111
var hash2 = hash.HashString("helloworld", Hashes.MurmurHash);
107112
var hash3 = hash.HashString("helloworl", Hashes.MurmurHash);
113+
var hash4 = hash.HashByte(System.Text.Encoding.Default.GetBytes("helloworl"));
108114

115+
Assert.AreEqual(hash1, hash0);
109116
Assert.AreEqual(hash1, hash2);
110117
Assert.AreNotEqual(hash2, hash3);
118+
Assert.AreEqual(hash3, hash4);
111119
}
112120

113121
[TestMethod]

projects/CatLib/Hashing/Hashing.cs

Lines changed: 105 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
using CatLib.API.Hashing;
1313
using CatLib.Hashing.Checksum;
14-
using CatLib.Hashing.HashString;
15-
using Murmur;
1614
using System;
1715
using System.Collections.Generic;
1816
using System.Security.Cryptography;
@@ -25,6 +23,16 @@ namespace CatLib.Hashing
2523
/// </summary>
2624
internal sealed class Hashing : IHashing
2725
{
26+
/// <summary>
27+
/// 校验类字典
28+
/// </summary>
29+
private readonly Dictionary<Checksums, Func<IChecksum>> checksumsMaker;
30+
31+
/// <summary>
32+
/// 非加密哈希字典
33+
/// </summary>
34+
private readonly Dictionary<Hashes, Func<HashAlgorithm>> hashByteMaker;
35+
2836
/// <summary>
2937
/// 校验类字典
3038
/// </summary>
@@ -40,22 +48,65 @@ internal sealed class Hashing : IHashing
4048
/// </summary>
4149
private readonly object syncRoot = new object();
4250

51+
/// <summary>
52+
/// 默认的校验算法
53+
/// </summary>
54+
private readonly Checksums defaultChecksum;
55+
56+
/// <summary>
57+
/// 默认的哈希算法
58+
/// </summary>
59+
private readonly Hashes defaultHash;
60+
4361
/// <summary>
4462
/// 哈希
4563
/// </summary>
46-
public Hashing()
64+
public Hashing(Checksums defaultChecksum, Hashes defaultHash)
4765
{
48-
checksumsDict = new Dictionary<Checksums, IChecksum>
49-
{
50-
{ Checksums.Crc32, new Crc32() },
51-
{ Checksums.Adler32, new Adler32() }
52-
};
66+
Guard.Requires<ArgumentNullException>(defaultChecksum != null);
67+
Guard.Requires<ArgumentNullException>(defaultHash != null);
5368

54-
hashByteDict = new Dictionary<Hashes, HashAlgorithm>
55-
{
56-
{ Hashes.MurmurHash , new Murmur32ManagedX86() },
57-
{ Hashes.Djb, new DjbHash() }
58-
};
69+
this.defaultChecksum = defaultChecksum;
70+
this.defaultHash = defaultHash;
71+
72+
checksumsMaker = new Dictionary<Checksums, Func<IChecksum>>();
73+
hashByteMaker = new Dictionary<Hashes, Func<HashAlgorithm>>();
74+
checksumsDict = new Dictionary<Checksums, IChecksum>();
75+
hashByteDict = new Dictionary<Hashes, HashAlgorithm>();
76+
}
77+
78+
/// <summary>
79+
/// 注册校验算法
80+
/// </summary>
81+
/// <param name="checksum">校验类类型</param>
82+
/// <param name="builder">构建器</param>
83+
public void RegisterChecksum(Checksums checksum, Func<IChecksum> builder)
84+
{
85+
Guard.Requires<ArgumentNullException>(checksum != null);
86+
Guard.Requires<ArgumentNullException>(builder != null);
87+
checksumsMaker.Add(checksum, builder);
88+
}
89+
90+
/// <summary>
91+
/// 注册校验算法
92+
/// </summary>
93+
/// <param name="hash">哈希类类型</param>
94+
/// <param name="builder">构建器</param>
95+
public void RegisterHash(Hashes hash, Func<HashAlgorithm> builder)
96+
{
97+
Guard.Requires<ArgumentNullException>(hash != null);
98+
Guard.Requires<ArgumentNullException>(builder != null);
99+
hashByteMaker.Add(hash, builder);
100+
}
101+
102+
/// <summary>
103+
/// 使用默认的校验算法计算校验和
104+
/// </summary>
105+
/// <param name="buffer">字节数组</param>
106+
/// <returns>校验和</returns>
107+
public long Checksum(byte[] buffer)
108+
{
109+
return Checksum(buffer, defaultChecksum);
59110
}
60111

61112
/// <summary>
@@ -64,13 +115,19 @@ public Hashing()
64115
/// <param name="buffer">字节数组</param>
65116
/// <param name="checksum">使用校验类类型</param>
66117
/// <returns>校验和</returns>
67-
public long Checksum(byte[] buffer, Checksums checksum = Checksums.Crc32)
118+
public long Checksum(byte[] buffer, Checksums checksum)
68119
{
69120
Guard.Requires<ArgumentNullException>(buffer != null);
70121
IChecksum checksumClass;
71122
if (!checksumsDict.TryGetValue(checksum, out checksumClass))
72123
{
73-
throw new RuntimeException("Undefiend Checksum:" + checksum);
124+
Func<IChecksum> checksumMaker;
125+
if (!checksumsMaker.TryGetValue(checksum, out checksumMaker)
126+
|| (checksumClass = checksumMaker.Invoke()) == null)
127+
{
128+
throw new RuntimeException("Undefiend Checksum:" + checksum);
129+
}
130+
checksumsDict[checksum] = checksumClass;
74131
}
75132
lock (syncRoot)
76133
{
@@ -105,13 +162,23 @@ public bool CheckPassword(string input, string hash)
105162
return BCrypt.Net.BCrypt.Verify(input, hash);
106163
}
107164

165+
/// <summary>
166+
/// 对输入值进行非加密哈希
167+
/// </summary>
168+
/// <param name="input">输入值</param>
169+
/// <returns>哈希值</returns>
170+
public uint HashString(string input)
171+
{
172+
return HashString(input, defaultHash);
173+
}
174+
108175
/// <summary>
109176
/// 对输入值进行非加密哈希
110177
/// </summary>
111178
/// <param name="input">输入值</param>
112179
/// <param name="hash">使用的哈希算法</param>
113180
/// <returns>哈希值</returns>
114-
public uint HashString(string input, Hashes hash = Hashes.MurmurHash)
181+
public uint HashString(string input, Hashes hash)
115182
{
116183
return HashString(input, Encoding.Default, hash);
117184
}
@@ -123,28 +190,47 @@ public uint HashString(string input, Hashes hash = Hashes.MurmurHash)
123190
/// <param name="encoding">编码</param>
124191
/// <param name="hash">使用的哈希算法</param>
125192
/// <returns>哈希值</returns>
126-
public uint HashString(string input, Encoding encoding, Hashes hash = Hashes.MurmurHash)
193+
public uint HashString(string input, Encoding encoding, Hashes hash)
127194
{
128195
Guard.Requires<ArgumentNullException>(input != null);
129196
Guard.Requires<ArgumentNullException>(encoding != null);
130197
var data = encoding.GetBytes(input);
131198
return HashByte(data, hash);
132199
}
133200

201+
/// <summary>
202+
/// 对输入值进行非加密哈希
203+
/// </summary>
204+
/// <param name="input">输入值</param>
205+
/// <returns>哈希值</returns>
206+
public uint HashByte(byte[] input)
207+
{
208+
return HashByte(input, defaultHash);
209+
}
210+
134211
/// <summary>
135212
/// 对输入值进行非加密哈希
136213
/// </summary>
137214
/// <param name="input">输入值</param>
138215
/// <param name="hash">使用的哈希算法</param>
139216
/// <returns>哈希值</returns>
140-
public uint HashByte(byte[] input, Hashes hash = Hashes.MurmurHash)
217+
public uint HashByte(byte[] input, Hashes hash)
141218
{
142219
Guard.Requires<ArgumentNullException>(input != null);
220+
Guard.Requires<ArgumentNullException>(hash != null);
221+
143222
HashAlgorithm hashStringClass;
144223
if (!hashByteDict.TryGetValue(hash, out hashStringClass))
145224
{
146-
throw new RuntimeException("Undefiend Hashing:" + hash);
225+
Func<HashAlgorithm> hashStringMaker;
226+
if (!hashByteMaker.TryGetValue(hash, out hashStringMaker)
227+
|| (hashStringClass = hashStringMaker.Invoke()) == null)
228+
{
229+
throw new RuntimeException("Undefiend Hashing:" + hash);
230+
}
231+
hashByteDict[hash] = hashStringClass;
147232
}
233+
148234
return BitConverter.ToUInt32(hashStringClass.ComputeHash(input), 0);
149235
}
150236
}

0 commit comments

Comments
 (0)