< Summary

Information
Class: Hash.Core.HashCalculate.HashType.NonCryptoHashProvider
Assembly: Hash.Core
File(s): /home/runner/work/HashCalculator/HashCalculator/src/Hash.Core/HashCalculate.cs
Line coverage
100%
Covered lines: 6
Uncovered lines: 0
Coverable lines: 6
Total lines: 126
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ComputeHash(...)100%11100%

File(s)

/home/runner/work/HashCalculator/HashCalculator/src/Hash.Core/HashCalculate.cs

#LineLine coverage
 1// Copyright © 2021-present Hibi_10000
 2//
 3// This file is part of HashCalculator program.
 4//
 5// This program is free software: you can redistribute it and/or modify
 6// it under the terms of the GNU General Public License as published by
 7// the Free Software Foundation, either version 3 of the License, or
 8// (at your option) any later version.
 9//
 10// This program is distributed in the hope that it will be useful,
 11// but WITHOUT ANY WARRANTY; without even the implied warranty of
 12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13// GNU General Public License for more details.
 14//
 15// You should have received a copy of the GNU General Public License
 16// along with this program. If not, see <http://www.gnu.org/licenses/>.
 17
 18using System;
 19using System.Collections.Generic;
 20using System.Collections.Immutable;
 21using System.IO;
 22using System.IO.Hashing;
 23using System.Linq;
 24using System.Security.Cryptography;
 25
 26namespace Hash.Core;
 27
 28public static class HashCalculate
 29{
 30    internal class HashType
 31    {
 32        internal static readonly ImmutableDictionary<string, HashType> Types = new Dictionary<string, HashType>
 33        {
 34            ["MD5"        ] = new(GetProvider(          MD5     .Create   ), true                      ),
 35            ["SHA1"       ] = new(GetProvider(          SHA1    .Create   ), true                      ),
 36            ["SHA256"     ] = new(GetProvider(          SHA256  .Create   ), true                      ),
 37            ["SHA384"     ] = new(GetProvider(          SHA384  .Create   ), true                      ),
 38            ["SHA512"     ] = new(GetProvider(          SHA512  .Create   ), true                      ),
 39            ["SHA3-256"   ] = new(GetProvider(          SHA3_256.Create   ), true, SHA3_256.IsSupported),
 40            ["SHA3-384"   ] = new(GetProvider(          SHA3_384.Create   ), true, SHA3_384.IsSupported),
 41            ["SHA3-512"   ] = new(GetProvider(          SHA3_512.Create   ), true, SHA3_512.IsSupported),
 42            ["CRC8"       ] = new(GetProvider(() => new CRC8_CCITT()      )                            ),
 43            ["CRC16-CCITT"] = new(GetProvider(() => new CRC16_CCITT()     ), true                      ),
 44            ["CRC16-IBM"  ] = new(GetProvider(() => new CRC16_IBM()       )                            ),
 45            ["CRC32"      ] = new(GetProvider(() => new CRC32()           ), true                      ),
 46            ["CRC32C"     ] = new(GetProvider(() => new CRC32C()          )                            ),
 47            ["CRC64-ECMA" ] = new(GetProvider(() => new CRC64_ECMA()      ), true                      ),
 48            ["CRC64-ISO"  ] = new(GetProvider(() => new CRC64_ISO()       )                            ),
 49            ["CRC64-XZ"   ] = new(GetProvider(() => new CRC64_XZ()        ), true                      ),
 50            ["RIPEMD160"  ] = new(GetProvider(() => new RIPEMD160Managed())                            ),
 51            ["xxHash32"   ] = new(GetProvider(() => new XxHash32()        )                            ),
 52            ["xxHash64"   ] = new(GetProvider(() => new XxHash64()        )                            ),
 53            ["xxHash3"    ] = new(GetProvider(() => new XxHash3()         ), true                      ),
 54            ["xxHash128"  ] = new(GetProvider(() => new XxHash128()       )                            ),
 55        }.ToImmutableDictionary();
 56
 57        internal readonly IHashProvider Provider;
 58        internal readonly bool Visible;
 59        internal readonly bool Supported;
 60
 61        private HashType(IHashProvider provider, bool visible = false, bool supported = true)
 62        {
 63            Provider = provider;
 64            Visible = visible;
 65            Supported = supported;
 66        }
 67
 68        private static HashProvider GetProvider(Func<HashAlgorithm> providerFunc)
 69        {
 70            return new HashProvider(providerFunc);
 71        }
 72
 73        private static NonCryptoHashProvider GetProvider(Func<NonCryptographicHashAlgorithm> providerFunc)
 74        {
 75            return new NonCryptoHashProvider(providerFunc);
 76        }
 77
 78        internal interface IHashProvider
 79        {
 80            internal byte[] ComputeHash(Stream stream);
 81        }
 82
 83        private class HashProvider(Func<HashAlgorithm> providerFunc) : IHashProvider
 84        {
 85            public byte[] ComputeHash(Stream stream)
 86            {
 87                return providerFunc().ComputeHash(stream);
 88            }
 89        }
 90
 191        private class NonCryptoHashProvider(Func<NonCryptographicHashAlgorithm> providerFunc) : IHashProvider
 92        {
 93            public byte[] ComputeHash(Stream stream)
 194            {
 195                NonCryptographicHashAlgorithm provider = providerFunc();
 196                provider.Append(stream);
 197                return provider.GetCurrentHash();
 198            }
 99        }
 100    }
 101
 102    public static string[] GetHashTypeNames(bool includeHidden = false)
 103    {
 104        return (
 105            from type in HashType.Types
 106            where type.Value.Supported && (includeHidden || type.Value.Visible)
 107            select type.Key
 108        ).ToArray();
 109    }
 110
 111    public static string? GetHash(string hashType, string filePath, bool upper, bool hyphen)
 112    {
 113        if (!HashType.Types.ContainsKey(hashType)) return null;
 114        if (!File.Exists(filePath)) return null;
 115        using FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
 116        return GetHash(hashType, fs, upper, hyphen);
 117    }
 118
 119    internal static string GetHash(string hashType, Stream stream, bool upper, bool hyphen)
 120    {
 121        byte[] bs = HashType.Types[hashType].Provider.ComputeHash(stream);
 122        string returnStr = BitConverter.ToString(bs);
 123        returnStr = upper ? returnStr.ToUpperInvariant() : returnStr.ToLowerInvariant();
 124        return hyphen ? returnStr : returnStr.Replace("-", "");
 125    }
 126}