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: typea: Tb: 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"); }, } }