• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

xoofx / Blake3.NET / 8123751251

02 Mar 2024 03:32PM UTC coverage: 69.393% (+0.2%) from 69.211%
8123751251

push

github

xoofx
Update ci with reusable workflows

37 of 70 branches covered (52.86%)

Branch coverage included in aggregate %.

226 of 309 relevant lines covered (73.14%)

3529.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.96
/src/Blake3/Hash.cs
1
// Copyright (c) Alexandre Mutel. All rights reserved.
2
// Licensed under the BSD-Clause 2 license.
3
// See license.txt file in the project root for full license information.
4

5
using System;
6
using System.Diagnostics.CodeAnalysis;
7
using System.Runtime.CompilerServices;
8
using System.Runtime.InteropServices;
9

10
namespace Blake3;
11

12
/// <summary>
13
/// An output of the default size, 32 bytes, which provides constant-time equality checking.
14
/// </summary>
15
/// <remarks>
16
/// This hash is returned by <see cref="Hasher.Hash(System.ReadOnlySpan{byte})"/>.
17
/// This hash struct provides structural equality.
18
/// </remarks>
19
public struct Hash : IEquatable<Hash>
20
{
21
    /// <summary>
22
    /// The size of this hash is 32 bytes.
23
    /// </summary>
24
    public const int Size = 32;
25

26
    // Use explicit fields to avoid garbage at debugging time
27
#pragma warning disable 169
28
    private byte _byte1;
29
    private byte _byte2;
30
    private byte _byte3;
31
    private byte _byte4;
32
    private byte _byte5;
33
    private byte _byte6;
34
    private byte _byte7;
35
    private byte _byte8;
36
    private byte _byte9;
37
    private byte _byte10;
38
    private byte _byte11;
39
    private byte _byte12;
40
    private byte _byte13;
41
    private byte _byte14;
42
    private byte _byte15;
43
    private byte _byte16;
44
    private byte _byte17;
45
    private byte _byte18;
46
    private byte _byte19;
47
    private byte _byte20;
48
    private byte _byte21;
49
    private byte _byte22;
50
    private byte _byte23;
51
    private byte _byte24;
52
    private byte _byte25;
53
    private byte _byte26;
54
    private byte _byte27;
55
    private byte _byte28;
56
    private byte _byte29;
57
    private byte _byte30;
58
    private byte _byte31;
59
    private byte _byte32;
60
#pragma warning restore 169
61

62
    /// <summary>
63
    /// Copies bytes to this hash. The input data must be 32 bytes.
64
    /// </summary>
65
    /// <param name="data">A 32-byte buffer.</param>
66
    public void CopyFromBytes(ReadOnlySpan<byte> data)
67
    {
68
        if (data.Length != 32) ThrowArgumentOutOfRange(data.Length);
6!
69
        data.CopyTo(this.AsSpan());
6✔
70
    }
6✔
71

72
    /// <summary>
73
    /// Creates a hash from an input data that must be 32 bytes.
74
    /// </summary>
75
    /// <param name="data">A 32-byte buffer.</param>
76
    /// <returns>The 32-byte hash.</returns>
77
    [SkipLocalsInit]
78
    public static Hash FromBytes(ReadOnlySpan<byte> data)
79
    {
80
        if (data.Length != 32) ThrowArgumentOutOfRange(data.Length);
6!
81
        var hash = new Hash();
6✔
82
        hash.CopyFromBytes(data);
6✔
83
        return hash;
6✔
84
    }
85

86
    public bool Equals(Hash other)
87
    {
88
        return this.AsSpan().SequenceCompareTo(other.AsSpan()) == 0;
2✔
89
    }
90

91
    public override bool Equals(object obj)
92
    {
93
        return obj is Hash other && Equals(other);
×
94
    }
95

96
    public override int GetHashCode()
97
    {
98
        var values = MemoryMarshal.Cast<byte, int>(this.AsSpan());
2✔
99
        int hashcode = 0;
2✔
100
        for (int i = 0; i < values.Length; i++)
36✔
101
        {
102
            hashcode = (hashcode * 397) ^ values[i];
16✔
103
        }
104
        return hashcode;
2✔
105
    }
106

107
    public override string ToString()
108
    {
109
        return string.Create(Size * 2, this, (span, hash) =>
17✔
110
        {
17✔
111
            var data = hash.AsSpan();
17✔
112
            for (int i = 0; i < data.Length; i++)
1,122✔
113
            {
17✔
114
                var b = data[i];
544✔
115
                span[i * 2] = (char)Hex[(b >> 4) & 0xF];
544✔
116
                span[i * 2 + 1] = (char)Hex[b & 0xF];
544✔
117
            }
17✔
118
        });
34✔
119
    }
120

121
    /// <summary>
122
    /// Creates a span from a hash. The span returned has to follow the same lifetime than the hash referenced.
123
    /// </summary>
124
    /// <returns>The hash of the span</returns>
125
    [UnscopedRef]
126
    public Span<byte> AsSpan()
127
    {
128
        return MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref this, 1));
29✔
129
    }
130

131
    public static bool operator ==(Hash left, Hash right)
132
    {
133
        return left.Equals(right);
×
134
    }
135

136
    public static bool operator !=(Hash left, Hash right)
137
    {
138
        return !left.Equals(right);
×
139
    }
140

141
    [DoesNotReturn]
142
    [MethodImpl(MethodImplOptions.NoInlining)]
143
    private static void ThrowArgumentOutOfRange(int size)
144
    {
145
        throw new ArgumentOutOfRangeException("data", $"Invalid size {size} of the data. Expecting 32");
×
146
    }
147

148
    private static ReadOnlySpan<byte> Hex => new ReadOnlySpan<byte>(new byte[]
1,088✔
149
    {
1,088✔
150
        (byte)'0',
1,088✔
151
        (byte)'1',
1,088✔
152
        (byte)'2',
1,088✔
153
        (byte)'3',
1,088✔
154
        (byte)'4',
1,088✔
155
        (byte)'5',
1,088✔
156
        (byte)'6',
1,088✔
157
        (byte)'7',
1,088✔
158
        (byte)'8',
1,088✔
159
        (byte)'9',
1,088✔
160
        (byte)'a',
1,088✔
161
        (byte)'b',
1,088✔
162
        (byte)'c',
1,088✔
163
        (byte)'d',
1,088✔
164
        (byte)'e',
1,088✔
165
        (byte)'f',
1,088✔
166
    });
1,088✔
167
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc