patterncppMinor
Citadel's VisualEncrypt and VisualDecrypt
Viewed 0 times
andcitadelvisualencryptvisualdecrypt
Problem
I was skimming through this paper out of boredom. On pages 5 and 6, the paper shows a simple encryption/decryption scheme that Citadel uses to obfuscate data. The algorithm basically XORs the next character with the previous character. The code is roughly this (ugly, I know):
I decided to make a more generic version of this code so that it could work on different containers and values:
Here are two sample cases of it being used:
```
#include
#include
#include
int main ()
{
// Test char
std::string plaintext = "Please encrypt me!" ;
std::vector cyphertext ;
VisualEncrypt (plaintext.cbegin (), plaintext.cend (), std::back_inserter (cyphertext)) ;
std::string decrypttext ;
VisualDecrypt (cyphertext.cbegin (), cyphertext.cend (), std::back_inserter (decrypttext)) ;
// Test long
long arr [] = {1, 2,
void VisualEncrypt (void *buffer, unsigned size) {
for (unsigned i = 1; i 0; --i) {
((unsigned char *) buffer) [i] ^= ((unsigned char *) buffer) [i - 1] ;
}
}I decided to make a more generic version of this code so that it could work on different containers and values:
template
OutputIterator VisualEncrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
if (begin == end) {
return destination ;
}
auto value = *begin ;
*destination++ = value ;
while (++begin != end) {
value ^= *begin ;
*destination++ = value ;
}
return destination ;
}
template
OutputIterator VisualDecrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
if (begin == end) {
return destination ;
}
auto value = *begin ;
*destination++ = value ;
while (++begin != end) {
auto temp = *begin ;
*destination++ = value ^ temp ;
value = temp ;
}
return destination ;
}
template
Iterator VisualEncrypt (Iterator begin, Iterator end)
{
return VisualEncrypt (begin, end, begin) ;
}
template
Iterator VisualDecrypt (Iterator begin, Iterator end)
{
return VisualDecrypt (begin, end, begin) ;
}Here are two sample cases of it being used:
```
#include
#include
#include
int main ()
{
// Test char
std::string plaintext = "Please encrypt me!" ;
std::vector cyphertext ;
VisualEncrypt (plaintext.cbegin (), plaintext.cend (), std::back_inserter (cyphertext)) ;
std::string decrypttext ;
VisualDecrypt (cyphertext.cbegin (), cyphertext.cend (), std::back_inserter (decrypttext)) ;
// Test long
long arr [] = {1, 2,
Solution
The way you handle the first element as a special case is cumbersome: you're basically unrolling the first iteration of the loop. You could just initialize
Alternatively, use a for-loop, which results in slightly more compact code and gets the pesky side-effect
value = 0 so that the first XOR just copies the input to the output.template
OutputIterator VisualEncrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits::value_type T;
T value = 0;
while (begin != end) {
value ^= *begin++;
*destination++ = value ;
}
return destination ;
}
template
OutputIterator VisualDecrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits::value_type T;
T value = 0;
while (begin != end) {
T temp = *begin++;
*destination++ = value ^ temp ;
value = temp ;
}
return destination ;
}Alternatively, use a for-loop, which results in slightly more compact code and gets the pesky side-effect
++ operators out of the way.template
OutputIterator VisualEncrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits::value_type T;
for (T value = 0; begin != end; ++begin, ++destination) {
*destination = (value ^= *begin); //
OutputIterator VisualDecrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits::value_type T;
for (T value = 0; begin != end; ++begin, ++destination) {
T temp = *begin;
*destination = value ^ temp;
value = temp;
}
return destination;
}Code Snippets
template <class InputIterator, class OutputIterator>
OutputIterator VisualEncrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
T value = 0;
while (begin != end) {
value ^= *begin++;
*destination++ = value ;
}
return destination ;
}
template <class InputIterator, class OutputIterator>
OutputIterator VisualDecrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
T value = 0;
while (begin != end) {
T temp = *begin++;
*destination++ = value ^ temp ;
value = temp ;
}
return destination ;
}template <class InputIterator, class OutputIterator>
OutputIterator VisualEncrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
for (T value = 0; begin != end; ++begin, ++destination) {
*destination = (value ^= *begin); // <-- Probably controversial one-liner
}
return destination;
}
template <class InputIterator, class OutputIterator>
OutputIterator VisualDecrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
for (T value = 0; begin != end; ++begin, ++destination) {
T temp = *begin;
*destination = value ^ temp;
value = temp;
}
return destination;
}Context
StackExchange Code Review Q#57420, answer score: 7
Revisions (0)
No revisions yet.