PHP Shift And Swap Cipher Algorithm

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
Here's an algorithm I came up with for manipulating byte data. It involves a shift key and a bit swap. The input bytes' 4 bits high and low are swapped initially, before the shift key adds to each byte in the sequence. Reversely, the values from the shift key are subtracted from each byte in the sequence before the bit swap occurs in order to reverse the effect.

Simple demo:
Code:
[NO-PARSE]#include <iostream>    // std::cout, std::endl
#include <vector>      // std::vector
#include <algorithm>   // std::copy, std::generate_n
#include <iterator>    // std::ostream_iterator
#include <random>      // std::mt19937

typedef unsigned char byte;

void GenerateShiftKey(std::vector<byte> &input_bytes, const unsigned key_len, const unsigned seed)
{
  std::mt19937 rand_generator(seed); // mt19937 - mersenne_twister_engine
  std::generate_n(input_bytes.begin(), key_len, [&rand_generator]() { return rand_generator() % (0xFF + 1); });
}

int main()
{
  std::vector<byte> input_data { 0x52, 0x3D, 0x44, 0x6F, 0x53, 0x53, 0x4F, 0x67, 0x67, 0x57, 0xAB };

  // std::vector<byte> shift_key  { 0x9E, 0x7B, 0xEF, 0xBD, 0xF7, 0xDE, 0x7B, 0xEF, 0xBD, 0xF7 };
  const int key_len = input_data.size();
  std::vector<byte> shift_key(key_len);
  GenerateShiftKey(shift_key, key_len, 17);

  std::cout << std::uppercase << std::hex;

  std::cout << "shift key : ";
  std::copy(shift_key.begin(), shift_key.end(), std::ostream_iterator<int>(std::cout, " "));
  std::endl(std::cout);


  int i = 0;
  std::for_each(input_data.begin(), input_data.end(), [&i, &shift_key, &input_data](byte b) {
    input_data[i] = ((b & 0xF) * (0xF + 1)) + (b >> 4) + shift_key[i % shift_key.size()];
    i++;
  });

  std::cout << "encrypted : ";
  std::copy(input_data.begin(), input_data.end(), std::ostream_iterator<int>(std::cout, " "));
  std::endl(std::cout);

  i = 0;
  std::for_each(input_data.begin(), input_data.end(), [&i, &shift_key, &input_data](byte b) {
    b -= shift_key[i % shift_key.size()];
    input_data[i] = ((b & 0xF) * (0xF + 1)) + (b >> 4);
    i++;
  });

  std::cout << "original  : ";
  std::copy(input_data.begin(), input_data.end(), std::ostream_iterator<int>(std::cout, " "));
  std::endl(std::cout);
}[/NO-PARSE]

Output:
Code:
shift key : 6F F1 8F 86 96 39 F0 AD 16 1F 44 
encrypted : 94 C4 D3 7C CB 6E E4 23 8C 94 FE 
original  : 52 3D 44 6F 53 53 4F 67 67 57 AB

The seed is important, if you're using the randomly generated key provided by the function. Otherwise, you can use your own series of bytes for the key. Right now, I've set it at an arbitrary value of 17 just for demonstration purposes.
 
Another strategy that I could've used for swapping 4 bits:
Code:
[plain]#include <iostream>

int main()
{
  int a = 0xA, b = 0xB;
  std::cout << std::hex << std::uppercase
            << "0x" << ((a << 4) | b) << '\n'
            << "0x" << ((b << 4) | a)
            << std::endl;
}[/plain]

Put into practice:
Code:
[NO-PARSE]int main()
{
  int x = 0xAB;
  std::cout << std::hex << std::uppercase;
  std::cout << "0x" << (((x << 4) & 0xFF) | (x >> 4))
            << '\n';
  std::cout << "0x" << (((x & 0xF) << 4) | (x >> 4))
            << std::endl;
}[/NO-PARSE]
 
Last edited:
Back
Top