language: C++11 (gcc-4.7.2)
date: 610 days 5 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <cassert>
#include <string>
#include <iostream>
 
void set_low_nibble(char& c, unsigned char nibble) {
    // assumes nibble has no bits set in the four higher bits)
    unsigned char& b = reinterpret_cast<unsigned char&>(c);
    b = (b & 0xF0) | nibble;
}
 
void set_high_nibble(char& c, unsigned char nibble) {
    unsigned char& b = reinterpret_cast<unsigned char&>(c);
    b = (b & 0x0F) | (nibble << 4);
}
 
unsigned char get_low_nibble(unsigned char c) {
    return c & 0x0F;
}
 
unsigned char get_high_nibble(unsigned char c) {
    return (c & 0xF0) >> 4;
}
 
static void crypt_enc(char *data, int size)
{
    char last;
    // Pass 2
    for (int i = 0; i < size; i++)
    {
        unsigned char old_low = get_low_nibble(data[i]);
        set_low_nibble(data[i], last);
        last = get_high_nibble(data[i]);
        set_high_nibble(data[i], old_low);
    }
    set_low_nibble(data[0], last);
}
 
static void crypt_dec(char *data, int size)
{
    char last;
    // Pass 2
    for (int i = size-1; i >= 0; i--)
    {
        unsigned char old_high = get_high_nibble(data[i]);
        set_high_nibble(data[i], last);
        last = get_low_nibble(data[i]);
        set_low_nibble(data[i], old_high);
    }
    set_high_nibble(data[size-1], last);
}
 
int main() {
        char in[] = { 0x21, 0x43, 0x65, char(0x87), 0 }; // note: with nibbles ordered low to high this is 12345678
        std::string s(in);
        crypt_enc(&s[0], s.size());
        char enc[] = { 0x18, 0x32, 0x54, 0x76, 0 }; // note: with nibbles ordered low to high this is 81234567
        assert(s == enc);
        crypt_dec(&s[0], s.size());
        assert(s == in);
}