From e55c2bc0833a685f7be31aa56f019198ad40da03 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Tue, 28 Mar 2023 11:44:15 +0200 Subject: [PATCH] added a simple reversible block wise shuffle --- permute.hh | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/permute.hh b/permute.hh index 283ffbd..27b8906 100644 --- a/permute.hh +++ b/permute.hh @@ -35,6 +35,48 @@ public: } }; +template +class ReversibleBlockShuffle +{ + static_assert(SIZE >= 2 * BLOCK, "SIZE not large enough"); + static_assert(SIZE % BLOCK == 0, "BLOCK does not divide SIZE"); + static constexpr int BLOCKS = SIZE / BLOCK; + int seq[SIZE-1]; +public: + ReversibleBlockShuffle() + { + CODE::Xorshift32 prng; + for (int j = 0; j < BLOCKS; ++j) { + if (j < BLOCKS-1) + seq[BLOCK*j] = j + prng() % (BLOCKS - j); + for (int i = 0; i < BLOCK-1; ++i) + seq[BLOCK*j+1+i] = i + prng() % (BLOCK - i); + } + } + template + void forward(TYPE *array) + { + for (int j = 0; j < BLOCKS; ++j) { + if (j < BLOCKS-1) + for (int i = 0; i < BLOCK; ++i) + std::swap(array[BLOCK*j+i], array[BLOCK*seq[BLOCK*j]+i]); + for (int i = 0; i < BLOCK-1; ++i) + std::swap(array[BLOCK*j+i], array[BLOCK*j+seq[BLOCK*j+1+i]]); + } + } + template + void reverse(TYPE *array) + { + for (int j = BLOCKS-1; j >= 0; --j) { + for (int i = BLOCK-2; i >= 0; --i) + std::swap(array[BLOCK*j+i], array[BLOCK*j+seq[BLOCK*j+1+i]]); + if (j < BLOCKS-1) + for (int i = 0; i < BLOCK; ++i) + std::swap(array[BLOCK*j+i], array[BLOCK*seq[BLOCK*j]+i]); + } + } +}; + template static void BitReversalPermute(TYPE *array) {