Skip to content

Instantly share code, notes, and snippets.

@arbelt
Created August 21, 2019 17:12
Show Gist options
  • Save arbelt/26dd1ccf920b35992e578ea8af0048ff to your computer and use it in GitHub Desktop.
Save arbelt/26dd1ccf920b35992e578ea8af0048ff to your computer and use it in GitHub Desktop.
simple R implementation of "optimus" algorithm for obfuscating numeric IDs. Original PHP implementation at https://github.com/jenssegers/optimus
## Super simple implementation of "optimus" algorithm. Easy and fast way to
## encrypt/decrypt numbers. To make it more user-friendly, the `.settings`
## function generates a prime number and mask from a supplied key string. This
## depends on a stable hash of the string, so it's probably a good idea to jot
## down the underlying numbers (prime and mask) in case something changes with
## the hash internals. You'll always be able to decrypt if you know the prime
## and mask.
library(digest)
library(gmp)
.key <- "myPassword"
.MAX_ID <- 2147483647L
.settings <- function(key = .key){
x <- readBin(digest(key, serialize = FALSE, raw = TRUE),
what = "integer", n = 2)
x <- abs(x)
p <- nextprime(x[1])
modulus(p) <- .MAX_ID
i <- inv.bigz(p, .MAX_ID)
mask <- x[2]
out <- list(p = p, i = i, mask = mask)
message("Encryption settings (keep these somewhere safe):")
message(stringr::str_glue("Prime: {as.integer(out$p)}"))
message(stringr::str_glue("Mask: {as.integer(out$mask)}"))
out
}
encrypt <- function(settings, ids){
bitwXor(as.integer(ids * settings$p), settings$mask)
}
decrypt <- function(settings, x){
as.integer(bitwXor(x, settings$mask) * settings$i)
}
## Usage:
# s <- .settings("mySuperSecretKey")
# y <- encrypt(s, 1:10)
# x <- decrypt(s, y)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment