-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathCommon.cs
More file actions
60 lines (55 loc) · 2.55 KB
/
Common.cs
File metadata and controls
60 lines (55 loc) · 2.55 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
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
namespace Utilities
{
public class Common
{
[SuppressMessage("Microsoft.Security.Cryptography", "CA5354:SHA1CannotBeUsed", Justification = "Not a security related usage - just generating probabilistically unique id to identify a column from its name.")]
public static Guid GenerateGuidFromName(string name)
{
// The algorithm below is following the guidance of http://www.ietf.org/rfc/rfc4122.txt
// Create a blob containing a 16 byte number representing the namespace
// followed by the unicode bytes in the name.
var bytes = new byte[name.Length * 2 + 16];
uint namespace1 = 0x482C2DB2;
uint namespace2 = 0xC39047c8;
uint namespace3 = 0x87F81A15;
uint namespace4 = 0xBFC130FB;
// Write the bytes most-significant byte first.
for (int i = 3; 0 <= i; --i)
{
bytes[i] = (byte)namespace1;
namespace1 >>= 8;
bytes[i + 4] = (byte)namespace2;
namespace2 >>= 8;
bytes[i + 8] = (byte)namespace3;
namespace3 >>= 8;
bytes[i + 12] = (byte)namespace4;
namespace4 >>= 8;
}
// Write out the name, most significant byte first
for (int i = 0; i < name.Length; i++)
{
bytes[2 * i + 16 + 1] = (byte)name[i];
bytes[2 * i + 16] = (byte)(name[i] >> 8);
}
// Compute the Sha1 hash
var sha1 = SHA1.Create(); // CodeQL [SM02196] False positive: this hash is not used for any sort of crytopgraphy
byte[] hash = sha1.ComputeHash(bytes);
// Create a GUID out of the first 16 bytes of the hash (SHA-1 create a 20 byte hash)
int a = (((((hash[3] << 8) + hash[2]) << 8) + hash[1]) << 8) + hash[0];
short b = (short)((hash[5] << 8) + hash[4]);
short c = (short)((hash[7] << 8) + hash[6]);
c = (short)((c & 0x0FFF) | 0x5000); // Set high 4 bits of octet 7 to 5, as per RFC 4122
Guid guid = new Guid(a, b, c, hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]);
return guid;
}
public static string StringIntern(string str)
{
return str != null ? string.Intern(str) : string.Empty;
}
}
}