You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Perhaps this can be avoided by using unmanaged memory or by fixing the position of the array in memory
@@ -104,87 +61,5 @@ internal static void InternalWipe<T>(ref T data)
104
61
{
105
62
data=default(T);
106
63
}
107
-
108
-
// constant time hex conversion
109
-
// see http://stackoverflow.com/a/14333437/445517
110
-
//
111
-
// An explanation of the weird bit fiddling:
112
-
//
113
-
// 1. `bytes[i] >> 4` extracts the high nibble of a byte
114
-
// `bytes[i] & 0xF` extracts the low nibble of a byte
115
-
// 2. `b - 10`
116
-
// is `< 0` for values `b < 10`, which will become a decimal digit
117
-
// is `>= 0` for values `b > 10`, which will become a letter from `A` to `F`.
118
-
// 3. Using `i >> 31` on a signed 32 bit integer extracts the sign, thanks to sign extension.
119
-
// It will be `-1` for `i < 0` and `0` for `i >= 0`.
120
-
// 4. Combining 2) and 3), shows that `(b-10)>>31` will be `0` for letters and `-1` for digits.
121
-
// 5. Looking at the case for letters, the last summand becomes `0`, and `b` is in the range 10 to 15. We want to map it to `A`(65) to `F`(70), which implies adding 55 (`'A'-10`).
122
-
// 6. Looking at the case for digits, we want to adapt the last summand so it maps `b` from the range 0 to 9 to the range `0`(48) to `9`(57). This means it needs to become -7 (`'0' - 55`).
123
-
// Now we could just multiply with 7. But since -1 is represented by all bits being 1, we can instead use `& -7` since `(0 & -7) == 0` and `(-1 & -7) == -7`.
124
-
//
125
-
// Some further considerations:
126
-
//
127
-
// * I didn't use a second loop variable to index into `c`, since measurement shows that calculating it from `i` is cheaper.
128
-
// * Using exactly `i < bytes.Length` as upper bound of the loop allows the JITter to eliminate bounds checks on `bytes[i]`, so I chose that variant.
129
-
// * Making `b` an int avoids unnecessary conversions from and to byte.
130
-
publicstaticstringToHexStringUpper(byte[]data)
131
-
{
132
-
if(data==null)
133
-
returnnull;
134
-
char[]c=newchar[data.Length*2];
135
-
intb;
136
-
for(inti=0;i<data.Length;i++)
137
-
{
138
-
b=data[i]>>4;
139
-
c[i*2]=(char)(55+b+(((b-10)>>31)&-7));
140
-
b=data[i]&0xF;
141
-
c[i*2+1]=(char)(55+b+(((b-10)>>31)&-7));
142
-
}
143
-
returnnewstring(c);
144
-
}
145
-
146
-
// Explanation is similar to ToHexStringUpper
147
-
// constant 55 -> 87 and -7 -> -39 to compensate for the offset 32 between lowercase and uppercase letters
148
-
publicstaticstringToHexStringLower(byte[]data)
149
-
{
150
-
if(data==null)
151
-
returnnull;
152
-
char[]c=newchar[data.Length*2];
153
-
intb;
154
-
for(inti=0;i<data.Length;i++)
155
-
{
156
-
b=data[i]>>4;
157
-
c[i*2]=(char)(87+b+(((b-10)>>31)&-39));
158
-
b=data[i]&0xF;
159
-
c[i*2+1]=(char)(87+b+(((b-10)>>31)&-39));
160
-
}
161
-
returnnewstring(c);
162
-
}
163
-
164
-
publicstaticbyte[]FromHexString(stringhexString)
165
-
{
166
-
if(hexString==null)
167
-
returnnull;
168
-
if(hexString.Length%2!=0)
169
-
thrownewFormatException("The hex string is invalid because it has an odd length");
0 commit comments