Memfrob

November 10, 2020

Memfrob is a light encryption algorithm that works by xor-ing 4210 = 001010102 with each input byte to create encrypted output; decryption is symmetric with encryption. Memfrob is roughly equivalent to ROT13 in cryptographic security.

Your task is to implement memfrob. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

3 Responses to “Memfrob”

  1. chaw said

    A quick solution using standard Scheme:

    (import (scheme base)
            (scheme write)
            (only (srfi 60)
                  bitwise-xor)
            (only (org eip10 okmij myenv)
                  assert))
    
    (define (memfrob-byte byt)
      (bitwise-xor byt 42))
    
    (assert (equal? '(42 0 43 41)
                    (map memfrob-byte '(0 42 1 3))))
    
    (define (memfrob-bytevector bytvec)
      (let* ((n (bytevector-length bytvec))
             (r (make-bytevector n)))
        (do ((i 0 (+ i 1)))
            ((>= i n) r)
          (bytevector-u8-set! r i (memfrob-byte (bytevector-u8-ref bytvec i))))))
    
    (assert (equal? #u8(42 0 43 41)
                    (memfrob-bytevector #u8(0 42 1 3))))
    
    (define (memfrob-string str)
      (utf8->string (memfrob-bytevector (string->utf8 str))))
    
    (assert (string=? "Hello, World!"
                      (memfrob-string (memfrob-string "Hello, World!"))))
    

  2. Alex B said

    In Python:

    def memfrob(msg):
        return bytes(c ^ 42 for c in msg)
    

    Input argument must be a bytes-like object.

  3. Daniel said

    Here are a few solutions in C. The first is a plain vanilla implementation, followed by an implementation that uses memfrob from the GNU C library, and then an implementation that uses AVX2 intrinsics (the other solutions—compiled with optimizations—are still faster in my tests on a large file).

    #include <stdio.h>
    
    int main(void) {
      char buffer[BUFSIZ];
      while (1) {
        size_t n = fread(buffer, 1, BUFSIZ, stdin);
        if (!n) break;
        for (int i = 0; i < n; ++i)
          buffer[i] ^= 42;
        fwrite(buffer, 1, n, stdout);
      }
    }
    
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <string.h>
    
    int main(void) {
      char buffer[BUFSIZ];
      while (1) {
        size_t n = fread(buffer, 1, BUFSIZ, stdin);
        if (!n) break;
        memfrob(buffer, n);
        fwrite(buffer, 1, n, stdout);
      }
    }
    
    // Requires -mavx2 compiler flag.
    
    #include <immintrin.h>
    #include <stdio.h>
    
    int main(void) {
      int bufsize = 8192;  // Must be divisible by 32.
      char buffer[bufsize];
      __m256i mask = _mm256_set1_epi8(42);
      while (1) {
        size_t n = fread(buffer, 1, bufsize, stdin);
        if (!n) break;
        for (int i = 0; i < bufsize; i += 32) {
          char* p = (char*)buffer + i;
          __m256i x = _mm256_loadu_si256((__m256i*)p);
          __m256i y = _mm256_xor_si256(x, mask);
          *((__m256i*)p) = y;
        }
        fwrite(buffer, 1, n, stdout);
      }
      return 0;
    }
    

    Example usage:

    $ echo "Programming Praxis" | ./a.out
    zXEMXKGGCDM
    zXKRCY
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: