xchacha20_pl/binchunking.pl

47 lines
1.5 KiB
Prolog

:- module(binchunking, [as_int_be/3, as_int_le/3, append_chunk/4, test_binchunking/0]).
as_int_be(W, Bytes, V1) :-
ground(Bytes), reverse(RevBytes, Bytes), as_int_le(W, RevBytes, V1).
as_int_be(W, Bytes, V1) :-
ground(V1), as_int_le(W, RevBytes, V1), reverse(RevBytes, Bytes).
as_int_le(0, [], 0) :- !.
as_int_le(W1, [B | Bytes], V1) :-
ground(W1), W1 > 0, succ(W0, W1),
ground(B), !,
as_int_le(W0, Bytes, V0), V1 is V0 * 256 + B.
as_int_le(W1, [B | Bytes], V1) :-
ground(W1), W1 > 0, succ(W0, W1),
ground(V1), !,
B is V1 mod 256, V0 is V1 div 256, as_int_le(W0, Bytes, V0).
as_int_le(W, Bytes, V) :- throw(invalid_as_int(W, Bytes, V)).
append_chunk(Size, Chunk, Remaining, Total) :-
length(Chunk, Size), append(Chunk, Remaining, Total).
append_chunk(Size, Total, [], Total) :-
length(Total, L), 0 < L, L < Size.
test_as_int :-
forall(
member(L/W = N, [
[]/0 = 0,
[0, 0]/2 = 0,
[255, 1]/2 = 511,
[255, 128]/2 = 33023
]),
(
assertion( (as_int_le(W, L, N1), N1 = N) ),
assertion( (as_int_le(W, L1, N), L1 = L) ),
reverse(L, Q),
assertion( (as_int_be(W, Q, N1), N1 = N) ),
assertion( (as_int_be(W, Q1, N), Q1 = Q) )
)
).
test_append_chunk :-
assertion( (append_chunk(2, C, Rem, [a, b, c]), C = [a, b], Rem= [c]) ),
assertion( (append_chunk(3, C, Rem, [a, b, c]), C = [a, b, c], Rem= []) ).
test_binchunking :-
test_as_int,
test_append_chunk.