- Notifications
You must be signed in to change notification settings - Fork1
📚 Provides a handy way to hash data using Adler32, CRC (8-bit to 82-bit, and customizable without bit restriction), MD5, SHA-1 and SHA-2 (256-bit, 384-bit and 512-bit), including HMAC keyed hashing for some types. Functions for encrypting and decrypting data with Rijndael (128-bit, 192-bit and 256-bit) are also offered
License
Roydl/Crypto
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
The idea was to create a simple way to hash any type of data. So, there are generic extensions for almost any type. A handful algorithms are currently offered, but more will be added over time. Some algorithms are performance optimized and probably more powerful than any other pure C# library of its kind.
$ dotnet add package Roydl.Crypto
Name | Bit Width | Algorithm | Type | Hardware Support |
---|---|---|---|---|
Adler-32 | 32-bit | Standard | Cyclic | |
CRC | from 8-bit to 82-bit | 88 presets available + customizable | Cyclic | iSCSI @ SSE4.2 CPU iSCSI+PKZip @ ARM |
MD5 | 128-bit | Built-in +HMAC keyed-hash support | Cryptographic | ✖️ |
SHA-1 | 160-bit | Built-in +HMAC keyed-hash support | Cryptographic | ✖️ |
SHA-2 | 256-bit 384-bit 512-bit | Built-in +HMAC keyed-hash support | Cryptographic | ✖️ |
Especially for Alder and CRC, the performance in software mode should be much better than with any other pure C# library, but similar to libraries that work with C/C++ imports. However, I couldn't find any other library with hardware support, not even with imports.
Algorithm | Library | Mode | Speed |
---|---|---|---|
Adler-32 | This | Software | 1566,2 MiB/s |
Adler-32 | This | Hardware | |
CRC-32 | Crc32.NET | Software | 1602,7 MiB/s |
CRC-32 | This | Software | 2040,9 MiB/s |
CRC-32 | This | Hardware | 8393.9 MiB/s |
SHA-256 | Built-in | Software | 1846,7 MiB/s |
In the test case, a 64 KiB packet with random bytes is generated, which is sent over and over again within 9 seconds by the function that computes the hash. During this process, it is determined several times how much data could be hashed within 1 second. It seems like 9 seconds is the sweet spot. Increasing this time does not provide more accurate results. However, repetitions offer better results by saving all results, determining the maximum and minimum values and thus identifying fluctuations. The most accurate result seems to be the average of 20 repetitions. You can find the test casehere.
TheGetChecksum
extension method retrieves astring representation of the computed hash.
Thevalue can be almost anything.bool,sbyte,byte,short,ushort,char,int,uint,long,ulong,Half,float,double,decimal,Enum,IntPtr,UIntPtr,Vector{T},Vector2,Vector3,Vector4,Matrix3x2,Matrix4x4,Plane,Quaternion,Complex,BigInteger,DateTime,DateTimeOffset,TimeSpan,Guid,Rune,Stream,StreamReader,FileInfo, anyIEnumerable{T}byte sequence, i.e.Array, or anyIEnumerable{T}char sequence, i.e.string, any many more.
Not every type makes sense, but is supported anyway.
stringhash=value.GetChecksum(ChecksumAlgo.Sha1);Console.WriteLine(hash);// Output:// 12a5ba5baa1664f73e6279f23354bd90c8981a81
However, astring containing a file path has an additional method.
stringhash=value.GetFileChecksum();// SHA-256 is used when `ChecksumAlgo` is undefined
TheGetCipher
extension method retrieves anunsigned 64-bit integer representation of the computed hash. It follows the same rules outlined earlier. This can be useful with cyclic computed hashes.
ulonghash=value.GetCipher(ChecksumAlgo.Crc64);
Note thatHMAC
keyed-hashing is only supported for cryptographic algorithms via instances by setting a secret key.
Sha512instance=Sha512.Create(newbyte[128]{/* some bytes */});
TheComputeHash
methods uses the secret key untilDestroySecretKey
is called.
instance.ComputeHash(value);
An instance provides a computed hash in several variants.
ReadOnlySpan<byte>rawHash=instance.RawHash;BigIntegercipher=instance.CipherHash;// The integral type depends on the bit length, e.g. CRC-32 is `UInt32`stringlowercase=instance.Hash;stringuppercase=instance.ToString(true);
Casting is also supported to get a hash.
byte[]copyOfRawHash=(byte[])instance;ulongcipher=(ulong)instance;// Numeric conversions are unchecked conversions of the `instance.CipherHash` fieldstringlowercase=(string)instance;
Instances also provide equality operators for quick comparison.
boolequ=(instance1==instance2);boolneq=(instance1!=instance2);
If you need a different CRC algorithm, you can easily create your own variation.
This is an example forCRC-32/POSIX
, but it should support many others from 8-bit to almost infinite bits.
constintwidth=32;constuintcheck=0x765e7680u;constuintpoly=0x04c11db7u;constuintinit=0x00000000u;constboolrefIn=false;constboolrefOut=false;constuintxorOut=0xffffffffu;constuintmask=0xffffffffu;constboolskipValidation=false;
Sets a newCrcConfig
with the constants from above. The data are automatically validated with the given check.
varcfg=newCrcConfig32(width,check,poly,init,refIn,refOut,xorOut,mask,skipValidation);
Compute the hash directly via the configuration structure.
cfg.ComputeHash(stream,outuintcipher);
Or load it into the CRC class which has more features, and compute the hash code from there.
Thevalue can be from typeStream,byte[],string,FileInfo, or astring containing a file path.
varcrc=newCrc<uint>(config);crc.ComputeHash(value);
As mentioned earlier, instances offer computed hashes in several variants. It follows the same rules that have already been explained above.
ReadOnlyMemory<byte>rawHash=crc.RawHash;uintcipher=crc.CipherHash;stringlowercase=crc.Hash;
Check out theCRC configuration manager to see more examples.
Name | Algorithm |
---|---|
Rijndael | 128 bit block size; optional:128 ,192 or256 bit key size,cipher andpadding modes |
byte[]password=newbyte[]{/* some bytes */};byte[]salt=newbyte[]{/* some bytes */};usingvaraes=newRijndael(password,salt,1000,SymmetricKeySize.Large);aes.Encrypt(streamToEncrypt,encryptedStream);aes.Decrypt(streamToDecrypt,decryptedStream);
- Star this Project ⭐ and show me that this project interests you 🤗
- Open an Issue ☕ to give me your feedback and tell me your ideas and wishes for the future 😎
- Open a Ticket 📫 if you don't have a GitHub account, you can contact me directly on my website 😉
- Donate by PayPal 💸 to buy me some cakes 🍰
Please note that I cannot fix bugs that are unknown to me. So do yourself and me the favor and get in touch with me. 🤕
About
📚 Provides a handy way to hash data using Adler32, CRC (8-bit to 82-bit, and customizable without bit restriction), MD5, SHA-1 and SHA-2 (256-bit, 384-bit and 512-bit), including HMAC keyed hashing for some types. Functions for encrypting and decrypting data with Rijndael (128-bit, 192-bit and 256-bit) are also offered