Function eql [src]
Compares two arrays in constant time (for a given length) and returns whether they are equal.
This function was designed to compare short cryptographic secrets (MACs, signatures).
For all other applications, use mem.eql() instead.
Prototype
pub fn eql(comptime T: type, a: T, b: T) bool
Parameters
T: type
a: T
b: T
Example
test eql {
const random = std.crypto.random;
const expect = std.testing.expect;
var a: [100]u8 = undefined;
var b: [100]u8 = undefined;
random.bytes(a[0..]);
random.bytes(b[0..]);
try expect(!eql([100]u8, a, b));
a = b;
try expect(eql([100]u8, a, b));
}
Source
pub fn eql(comptime T: type, a: T, b: T) bool {
switch (@typeInfo(T)) {
.array => |info| {
const C = info.child;
if (@typeInfo(C) != .int) {
@compileError("Elements to be compared must be integers");
}
var acc = @as(C, 0);
for (a, 0..) |x, i| {
acc |= x ^ b[i];
}
const s = @typeInfo(C).int.bits;
const Cu = std.meta.Int(.unsigned, s);
const Cext = std.meta.Int(.unsigned, s + 1);
return @as(bool, @bitCast(@as(u1, @truncate((@as(Cext, @as(Cu, @bitCast(acc))) -% 1) >> s))));
},
.vector => |info| {
const C = info.child;
if (@typeInfo(C) != .int) {
@compileError("Elements to be compared must be integers");
}
const acc = @reduce(.Or, a ^ b);
const s = @typeInfo(C).int.bits;
const Cu = std.meta.Int(.unsigned, s);
const Cext = std.meta.Int(.unsigned, s + 1);
return @as(bool, @bitCast(@as(u1, @truncate((@as(Cext, @as(Cu, @bitCast(acc))) -% 1) >> s))));
},
else => {
@compileError("Only arrays and vectors can be compared");
},
}
}