Skip to content

Commit

Permalink
follow deno styleguide
Browse files Browse the repository at this point in the history
  • Loading branch information
GirkovArpa committed Aug 12, 2020
1 parent c62d39c commit ff1b098
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
55 changes: 35 additions & 20 deletions main.ts → mod.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,68 @@
'use strict';
/** This module is browser compatible. */

type char = string;
'use strict';

const ALPHABET = 'abcdefghijklmnopqrstuvwxyz';
const ALL_LOWER_CASE = /[a-z]/g;
const ENTIRELY_LOWER_CASE = /^[a-z]*$/;

export const validate = (...args: string[]): void => {
/** Throw an error if any string argument is not a lower-case ASCII letter string. */
export function validate(...args: string[]): void {
args.forEach((s: string) => {
if (!ENTIRELY_LOWER_CASE.test(s))
throw new Error(`String must consist of lowercase letters only. Received ${JSON.stringify(s)}.`);
});
}

export const mod = (n: number, m: number): number => ((n % m) + m) % m;
/** Alternative to `%` that works on negative numbers. */
export function mod(n: number, m: number): number {
return ((n % m) + m) % m;
}

export const rotate = (s: string): string => {
const [c]: char = s;
/** Shift each character in a string to the right, wrapping around. */
export function rotate(s: string): string {
const [c]: string = s;
const sliced: string = s.slice(1);
const rotated: string = sliced.concat(c);
return rotated;
}

export const swap = (s: string, i: number, j: number): string => {
/** Swap a pair of characters in a string. */
export function swap(s: string, i: number, j: number): string {
let a: string[] = [...s];
[a[i], a[j]] = [a[j], a[i]];
const swapped: string = a.join('');
return swapped;
}

const nothingIfIn = (set: Set<char>) => (c: char): string => set.has(c) ? '' : c;
/** Returns a closure which returns an empty string if the given `Set` contains the given `string`. */
function nothingIfIn(set: Set<string>) {
return (c: string): string => set.has(c) ? '' : c;
}

export const permutate = (key: string): string => {
const set: Set<char> = new Set(key);
/** Returns the alphabet with all `key` letters moved to the beginning. */
export function permutate(key: string): string {
const set: Set<string> = new Set(key);
const uniques: string = [...set].join('');
const diff: string = ALPHABET.replace(ALL_LOWER_CASE, nothingIfIn(set));
const perm: string = uniques.concat(diff);
return perm;
}

export const encrypt = (pt: string, pw: string, k: string, ct = '', perm: string = permutate(k)): string => {
/** Encrypts a string using the provided password and key, all of which must consist of characters in the range `[a-z]`.
*
* const ciphertext = encrypt('helloworld', 'foo', 'bar');
*/
export function encrypt(pt: string, pw: string, k: string, ct = '', perm: string = permutate(k)): string {
validate(pt, pw, k, ct, perm);
const [pwC]: char = pw;
const [pwC]: string = pw;
const pwC_i: number = ALPHABET.indexOf(pwC);
const [permC]: char = perm;
const [permC]: string = perm;
const permC_i: number = ALPHABET.indexOf(permC);
const shift: number = (pwC_i + permC_i + 2);
const [ptC]: char = pt;
const [ptC]: string = pt;
const ctC_i: number = (shift + perm.indexOf(ptC)) % ALPHABET.length;
const ctC: char = perm[ctC_i];
const ctC: string = perm[ctC_i];
const ptC_i: number = perm.indexOf(ptC);

const ptSlice: string = pt.slice(1);
Expand All @@ -59,16 +73,17 @@ export const encrypt = (pt: string, pw: string, k: string, ct = '', perm: string
return (pt.length === 0) ? ct : encrypt(ptSlice, pwRotated, k, ctNew, permSwapped);
}

export const decrypt = (ct: string, pw: string, k: string, pt = '', perm: string = permutate(k)): string => {
/** Decrypts a string consisting only of characters in the range `[a-z]`. */
export function decrypt(ct: string, pw: string, k: string, pt = '', perm: string = permutate(k)): string {
validate(pt, pw, k, ct, perm);
const [pwC]: char = pw;
const [pwC]: string = pw;
const pwC_i: number = ALPHABET.indexOf(pwC);
const [permC]: char = perm;
const [permC]: string = perm;
const permC_i: number = ALPHABET.indexOf(permC);
const shift: number = -(pwC_i + permC_i + 2);
const [ctC]: char = ct;
const [ctC]: string = ct;
const ptC_i: number = mod((shift + perm.indexOf(ctC)), ALPHABET.length);
const ptC: char = perm[ptC_i];
const ptC: string = perm[ptC_i];
const ctC_i: number = perm.indexOf(ctC);

const ctSlice: string = ct.slice(1);
Expand Down
2 changes: 1 addition & 1 deletion test.ts → mod_test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

import { assertEquals } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { encrypt, decrypt, permutate, swap, rotate, mod, validate } from './main.ts';
import { encrypt, decrypt, permutate, swap, rotate, mod, validate } from './mod.ts';

Deno.test('validate', () => {
try {
Expand Down

0 comments on commit ff1b098

Please sign in to comment.