Skip to content

Instantly share code, notes, and snippets.

@pascalduez
Last active June 14, 2022 22:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pascalduez/adad260a36101ce58dcc to your computer and use it in GitHub Desktop.
Save pascalduez/adad260a36101ce58dcc to your computer and use it in GitHub Desktop.
Caesar cipher in Sass.
// ----
// Sass (v3.3.8)
// Compass (v1.0.0.alpha.19)
// ----
// Caesar cipher
// https://en.wikipedia.org/wiki/Caesar_cipher
// Get char code from `$str` at `$index` in range [1-52][A-Za-z].
// ––––––––
// @param [string] $str
// @param [number] $index
// ––––––––
// @return [number]
@function char-code-at($str, $index: 1) {
$chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
@return str-index($chars, str-slice($str, $index, $index));
}
// Get char at `$index` in range [1-52][A-Za-z].
// ––––––––
// @param [number] $index
// ––––––––
// @return [string]
@function from-char-code($index) {
$chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
@return str-slice($chars, $index, $index);
}
// Test whether `$value` is containedd between `$min` and `$max`.
// --------
// @param [number] $min: minimum range value
// @param [number] $max: maximum range value
// @param [number] $value: the value to be tested
// --------
// @return [boolean]
@function is-in-range($min, $max, $value) {
@return ($value >= $min) and ($value <= $max);
}
// Caesar cipher encoder/decoder.
// --------
// @param [stringr] $message
// @param [number] $shift
// @param [string] $op: encrypt | decrupt
// --------
// @return [string]
@function caesar($message, $shift: 1, $op: 'encrypt') {
@if type-of($shift) != number {
@warn '`$shift` must be a number, type-of($shift) given.';
}
@if not is-in-range(0, 26, abs($shift)) {
@warn '`$shift` must in range [0-26].';
}
$result: '';
@if $op == 'decrypt' {
$shift: (26 - $shift);
}
@for $i from 1 through str-length($message) {
$code: char-code-at($message, $i);
@if $code {
// Uppercase $col <= 26
// Lowercase $col > 26
$start: if($code > 26, 27, 1);
$match: ((($code - $start) + $shift) % 26) + $start;
$result: $result + from-char-code($match);
}
@else {
// Non [A-Za-z] char.
$result: $result + str-slice($message, $i, $i);
}
}
@return $result;
}
// Alias
@function rot($message, $shift: 1, $op: 'encrypt') {
@return caesar($message, $shift, $op);
}
// Tests
caesar {
$fixture: (
('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 13, 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'),
('Caesar cipher', 1, 'Dbftbs djqifs'),
('Caesar cipher', 3, 'Fdhvdu flskhu'),
('Caesar cipher', 5, 'Hfjxfw hnumjw'),
('Caesar cipher', -6, 'Wuymul wcjbyl')
);
/* Encrypt */
$tests: '';
@each $test in $fixture {
$pass: rot(nth($test, 1), nth($test, 2)) == nth($test, 3);
$tests: $tests + if($pass, '✔ ', 'X ');
}
tests: $tests;
/* Decrypt */
$tests: '';
@each $test in $fixture {
$pass: rot(nth($test, 3), nth($test, 2), 'decrypt') == nth($test, 1);
$tests: $tests + if($pass, '✔ ', 'X ');
}
tests: $tests;
}
@charset "UTF-8";
caesar {
/* Encrypt */
tests: "✔ ✔ ✔ ✔ ✔ ";
/* Decrypt */
tests: "✔ ✔ ✔ ✔ ✔ ";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment