From 609502b04bc7c21269ebe5340016775827fc3981 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 20 Feb 2021 16:47:52 +0000 Subject: [PATCH] Add utility function 'memxor'. --- misc.h | 9 +++++++++ utils.c | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/misc.h b/misc.h index 7b4945ef..7b4012b6 100644 --- a/misc.h +++ b/misc.h @@ -430,4 +430,13 @@ LoadFileStatus lf_load(LoadedFile *lf, const Filename *filename); static inline ptrlen ptrlen_from_lf(LoadedFile *lf) { return make_ptrlen(lf->data, lf->len); } +/* Set the memory block of 'size' bytes at 'out' to the bitwise XOR of + * the two blocks of the same size at 'in1' and 'in2'. + * + * 'out' may point to exactly the same address as one of the inputs, + * but if the input and output blocks overlap in any other way, the + * result of this function is not guaranteed. No memmove-style effort + * is made to handle difficult overlap cases. */ +void memxor(uint8_t *out, const uint8_t *in1, const uint8_t *in2, size_t size); + #endif diff --git a/utils.c b/utils.c index df128a22..6f7e69a7 100644 --- a/utils.c +++ b/utils.c @@ -1073,3 +1073,29 @@ void write_c_string_literal(FILE *fp, ptrlen str) fprintf(fp, "\\%03o", (unsigned char)c); } } + +void memxor(uint8_t *out, const uint8_t *in1, const uint8_t *in2, size_t size) +{ + switch (size & 15) { + case 0: + while (size >= 16) { + *out++ = *in1++ ^ *in2++; + case 15: *out++ = *in1++ ^ *in2++; + case 14: *out++ = *in1++ ^ *in2++; + case 13: *out++ = *in1++ ^ *in2++; + case 12: *out++ = *in1++ ^ *in2++; + case 11: *out++ = *in1++ ^ *in2++; + case 10: *out++ = *in1++ ^ *in2++; + case 9: *out++ = *in1++ ^ *in2++; + case 8: *out++ = *in1++ ^ *in2++; + case 7: *out++ = *in1++ ^ *in2++; + case 6: *out++ = *in1++ ^ *in2++; + case 5: *out++ = *in1++ ^ *in2++; + case 4: *out++ = *in1++ ^ *in2++; + case 3: *out++ = *in1++ ^ *in2++; + case 2: *out++ = *in1++ ^ *in2++; + case 1: *out++ = *in1++ ^ *in2++; + size -= 16; + } + } +}