From ff1b098a068fd5d1794eaa4529671f838029e277 Mon Sep 17 00:00:00 2001 From: GirkovArpa Date: Tue, 11 Aug 2020 21:37:30 -0500 Subject: [PATCH] follow deno styleguide --- main.ts => mod.ts | 55 +++++++++++++++++++++++++++--------------- test.ts => mod_test.ts | 2 +- 2 files changed, 36 insertions(+), 21 deletions(-) rename main.ts => mod.ts (52%) rename test.ts => mod_test.ts (97%) diff --git a/main.ts b/mod.ts similarity index 52% rename from main.ts rename to mod.ts index d8c7276..8feffed 100644 --- a/main.ts +++ b/mod.ts @@ -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) => (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) { + return (c: string): string => set.has(c) ? '' : c; +} -export const permutate = (key: string): string => { - const set: Set = new Set(key); +/** Returns the alphabet with all `key` letters moved to the beginning. */ +export function permutate(key: string): string { + const set: Set = 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); @@ -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); diff --git a/test.ts b/mod_test.ts similarity index 97% rename from test.ts rename to mod_test.ts index 2491cf0..3e2dd25 100644 --- a/test.ts +++ b/mod_test.ts @@ -1,7 +1,7 @@ 'use strict'; import { assertEquals } from 'https://deno.land/std@0.64.0/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 {