Memfrob

November 10, 2020

We give a function that performs encryption, and leave it to the reader to wrap that in a function that handles files:

(define (memfrob str)
   (define (frob c)
     (integer->char (bitwise-xor (char->integer c) 42)))
   (list->string (map frob (string->list str))))

 > (memfrob (memfrob "Programming Praxis"))
   "Programming Praxis" 

You can run the program at http://ideone.com/RnJDWB.

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: