From 63c73bbb92ec856e71fa77e970f6f84dd2c6bda0 Mon Sep 17 00:00:00 2001 From: wes Date: Fri, 15 Nov 2019 14:01:29 -0500 Subject: [PATCH 1/3] rotateString tests passing --- Crypto/src/{ => main/java/crypto}/ROT13.java | 12 ++++++-- .../src/{ => test/java/crypto}/ROT13Test.java | 2 ++ README.md | 28 +++++++++---------- SimpleCrypt.iml | 16 +++++++++++ 4 files changed, 42 insertions(+), 16 deletions(-) rename Crypto/src/{ => main/java/crypto}/ROT13.java (55%) rename Crypto/src/{ => test/java/crypto}/ROT13Test.java (99%) create mode 100644 SimpleCrypt.iml diff --git a/Crypto/src/ROT13.java b/Crypto/src/main/java/crypto/ROT13.java similarity index 55% rename from Crypto/src/ROT13.java rename to Crypto/src/main/java/crypto/ROT13.java index 1c58731..e7e34da 100644 --- a/Crypto/src/ROT13.java +++ b/Crypto/src/main/java/crypto/ROT13.java @@ -1,8 +1,11 @@ +package crypto; + import static java.lang.Character.isLowerCase; import static java.lang.Character.isUpperCase; import static java.lang.Character.toLowerCase; public class ROT13 { + private static final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); ROT13(Character cs, Character cf) { } @@ -25,8 +28,13 @@ public String decrypt(String text) { } public static String rotate(String s, Character c) { - - return ""; + StringBuilder rotated = new StringBuilder(); + int delta = Math.abs(c.compareTo(s.charAt(0))); + for (int i = 0; i < s.length(); i++) { + char in = (i+delta < s.length()) ? s.charAt(i+delta) : s.charAt(i+delta - s.length()); + rotated.append(in); + } + return rotated.toString(); } } diff --git a/Crypto/src/ROT13Test.java b/Crypto/src/test/java/crypto/ROT13Test.java similarity index 99% rename from Crypto/src/ROT13Test.java rename to Crypto/src/test/java/crypto/ROT13Test.java index 400c38b..a1e9bb8 100644 --- a/Crypto/src/ROT13Test.java +++ b/Crypto/src/test/java/crypto/ROT13Test.java @@ -1,3 +1,5 @@ +package crypto; + import org.junit.Test; import static org.junit.Assert.*; diff --git a/README.md b/README.md index 7b11728..12b7d2f 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ a simple set of crypt problems. ### Part 1 Create a few ciphers. Use String inside of your classes. -* ROT13 - take the 26 letters of the alphabet and create a `String <- crypt(String)` method in the ROT13 class +* crypto.ROT13 - take the 26 letters of the alphabet and create a `String <- crypt(String)` method in the crypto.ROT13 class * crypt("Why did the chicken cross the road?") should produce "Jul qvq gur puvpxra pebff gur ebnq?" * crypt("Gb trg gb gur bgure fvqr!") should produce "To get to the other side!" -* Make a constructor that takes two arguments to set the cipher correspondence. `ROT13 superSecure = new ROT13("a","m");` +* Make a constructor that takes two arguments to set the cipher correspondence. `crypto.ROT13 superSecure = new crypto.ROT13("a","m");` * this defines the SHIFT of the two Character arrays. -* Caesar - make a subclass of ROT13 that implements the famous caesar cipher. +* Caesar - make a subclass of crypto.ROT13 that implements the famous caesar cipher. * Create you own cipher, using a different set of ### Part 2 @@ -19,45 +19,45 @@ Prove that when you read in (sonnet18.enc), run the same crypt again, and prove ## Explanation -ROT13 ("rotate by 13 places", sometimes hyphenated ROT-13) is a simple letter substitution cipher that replaces a letter with the 13th letter after it, in the alphabet. ROT13 is a special case of the Caesar cipher, developed in ancient Rome. +crypto.ROT13 ("rotate by 13 places", sometimes hyphenated ROT-13) is a simple letter substitution cipher that replaces a letter with the 13th letter after it, in the alphabet. crypto.ROT13 is a special case of the Caesar cipher, developed in ancient Rome. -Because there are 26 letters (2×13) in the basic Latin alphabet, ROT13 is its own inverse; that is, to undo ROT13, the same algorithm is applied, so the same action can be used for encoding and decoding. The algorithm provides virtually no cryptographic security, and is often cited as a canonical example of weak encryption. +Because there are 26 letters (2×13) in the basic Latin alphabet, crypto.ROT13 is its own inverse; that is, to undo crypto.ROT13, the same algorithm is applied, so the same action can be used for encoding and decoding. The algorithm provides virtually no cryptographic security, and is often cited as a canonical example of weak encryption. -ROT13 is used in online forums as a means of hiding spoilers, punchlines, puzzle solutions, and offensive materials from the casual glance. ROT13 has been described as the "Usenet equivalent of a magazine printing the answer to a quiz upside down".[2] ROT13 has inspired a variety of letter and word games on-line, and is frequently mentioned in newsgroup conversations. +crypto.ROT13 is used in online forums as a means of hiding spoilers, punchlines, puzzle solutions, and offensive materials from the casual glance. crypto.ROT13 has been described as the "Usenet equivalent of a magazine printing the answer to a quiz upside down".[2] crypto.ROT13 has inspired a variety of letter and word games on-line, and is frequently mentioned in newsgroup conversations. -Applying ROT13 to a piece of text merely requires examining its alphabetic characters and replacing each one by the letter 13 places further along in the alphabet, wrapping back to the beginning if necessary.[3] A becomes N, B becomes O, and so on up to M, which becomes Z, then the sequence continues at the beginning of the alphabet: N becomes A, O becomes B, and so on to Z, which becomes M. Only those letters which occur in the English alphabet are affected; numbers, symbols, whitespace, and all other characters are left unchanged. +Applying crypto.ROT13 to a piece of text merely requires examining its alphabetic characters and replacing each one by the letter 13 places further along in the alphabet, wrapping back to the beginning if necessary.[3] A becomes N, B becomes O, and so on up to M, which becomes Z, then the sequence continues at the beginning of the alphabet: N becomes A, O becomes B, and so on to Z, which becomes M. Only those letters which occur in the English alphabet are affected; numbers, symbols, whitespace, and all other characters are left unchanged. ```Java String s = "we hold these truths to be self evident"; -//WHEN you create a ROT13 with 'a' and 'n' THEN +crypto.ROT13 -if (crypt(crypt(s)) == s) { +if (crcrypto.ROT13rypt(s)) == s) { return true; } //if anything else, you must use the encrypt/decrypt pair. ``` -In other words, two successive applications of ROT13 restore the original text (in mathematics, this is sometimes called an involution; in cryptography, a reciprocal cipher). +In other words, two successive applications of ROT13 restore the original text (in crypto.ROT13matics, this is sometimes called an involution; in cryptography, a reciprocal cipher). The transformation can be done using a lookup table, such as the following: ``` // for ROT13('a', 'n') -Input ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz +Input ABCDEFGHIJKLMNcrypto.ROT13TUVWXYZ abcdefghijklmnopqrstuvwxyz Output NOPQRSTUVWXYZABCDEFGHIJKLM nopqrstuvwxyzabcdefghijklm // for ROT13('a', 'd') -Input ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz +Input ABCDEFGHIJKLMNcrypto.ROT13TUVWXYZ abcdefghijklmnopqrstuvwxyz Output DEFGHIJKLMNOPQRSTUVWXYZABC defghijklmnopqrstuvwxyzabc ``` For example, in the following joke, the punchline has been obscured by ROT13: ``` -Why did the chicken cross the road? +Why did the chicken croscrypto.ROT13 road? Gb trg gb gur bgure fvqr! ``` -Transforming the entire text via ROT13 form, the answer to the joke is revealed: +Transforming the entire text via ROT13 form, the answer to the joke icrypto.ROT13ealed: ``` Jul qvq gur puvpxra pebff gur ebnq? To get to the other side! diff --git a/SimpleCrypt.iml b/SimpleCrypt.iml new file mode 100644 index 0000000..6effe39 --- /dev/null +++ b/SimpleCrypt.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From cdd41a4664c7beb0106e67f141fed63bc0f7f66d Mon Sep 17 00:00:00 2001 From: wes Date: Fri, 15 Nov 2019 15:43:49 -0500 Subject: [PATCH 2/3] all tests passing --- Crypto/src/main/java/crypto/ROT13.java | 42 +++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/Crypto/src/main/java/crypto/ROT13.java b/Crypto/src/main/java/crypto/ROT13.java index e7e34da..770cae6 100644 --- a/Crypto/src/main/java/crypto/ROT13.java +++ b/Crypto/src/main/java/crypto/ROT13.java @@ -1,13 +1,16 @@ package crypto; +import java.util.Arrays; + import static java.lang.Character.isLowerCase; import static java.lang.Character.isUpperCase; import static java.lang.Character.toLowerCase; public class ROT13 { - private static final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); - + private final char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + private Integer delta; ROT13(Character cs, Character cf) { + delta = cf.compareTo(cs); } ROT13() { @@ -15,21 +18,46 @@ public class ROT13 { public String crypt(String text) throws UnsupportedOperationException { + delta = 13; + return encrypt(text); + } - return ""; + public Integer getAlphabetIndex(char letter) { + Integer index = -1; + for (int i = 0; i < alphabet.length; i++) { + if (String.valueOf(letter).toUpperCase().equals(String.valueOf(alphabet[i]))) { + index = i; + break; + } + } + return index; } public String encrypt(String text) { - return text; + StringBuilder encrypted = new StringBuilder(); + for (int i = 0; i < text.length(); i++) { + Integer index = getAlphabetIndex(text.charAt(i)) + delta; + char in = (!String.valueOf(text.charAt(i)).matches("[A-Za-z]")) ? + text.charAt(i) : + (index < alphabet.length) ? + alphabet[index] : + alphabet[index - alphabet.length]; + + encrypted.append( + (i == 0 || in == ' ') ? in : String.valueOf(in).toLowerCase()); + } + return encrypted.toString(); } public String decrypt(String text) { - return text; + delta = alphabet.length - delta; + + return encrypt(text); } - public static String rotate(String s, Character c) { + public String rotate(String s, Character c) { StringBuilder rotated = new StringBuilder(); - int delta = Math.abs(c.compareTo(s.charAt(0))); + int delta = c.compareTo(s.charAt(0)); for (int i = 0; i < s.length(); i++) { char in = (i+delta < s.length()) ? s.charAt(i+delta) : s.charAt(i+delta - s.length()); rotated.append(in); From 6c87d3ded91ca9af4ac724055e8030f2ce46408c Mon Sep 17 00:00:00 2001 From: wes Date: Fri, 15 Nov 2019 16:34:59 -0500 Subject: [PATCH 3/3] SonnetEncryptor functioning and tests passing --- Crypto/src/main/java/crypto/ROT13.java | 26 ++++++++++++++----- .../src/main/java/crypto/SonnetEncryptor.java | 18 +++++++++++++ Crypto/src/test/java/crypto/ROT13Test.java | 3 +++ .../test/java/crypto/TestSonnetEncryptor.java | 26 +++++++++++++++++++ 4 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 Crypto/src/main/java/crypto/SonnetEncryptor.java create mode 100644 Crypto/src/test/java/crypto/TestSonnetEncryptor.java diff --git a/Crypto/src/main/java/crypto/ROT13.java b/Crypto/src/main/java/crypto/ROT13.java index 770cae6..128320a 100644 --- a/Crypto/src/main/java/crypto/ROT13.java +++ b/Crypto/src/main/java/crypto/ROT13.java @@ -37,18 +37,30 @@ public String encrypt(String text) { StringBuilder encrypted = new StringBuilder(); for (int i = 0; i < text.length(); i++) { Integer index = getAlphabetIndex(text.charAt(i)) + delta; - char in = (!String.valueOf(text.charAt(i)).matches("[A-Za-z]")) ? + Character in = (!isAlpha(text.charAt(i))) ? text.charAt(i) : (index < alphabet.length) ? alphabet[index] : alphabet[index - alphabet.length]; - - encrypted.append( - (i == 0 || in == ' ') ? in : String.valueOf(in).toLowerCase()); + encrypted.append(matchCase(text.charAt(i), in)); } return encrypted.toString(); } + public Character matchCase(Character in, Character out) { + if (isUpper(in)) out = out.toString().toUpperCase().charAt(0); + else out = out.toString().toLowerCase().charAt(0); + return out; + } + + public Boolean isUpper(Character a) { + return String.valueOf(a).matches("[A-Z]"); + } + + public Boolean isAlpha(Character c) { + return String.valueOf(c).matches("[A-Za-z]"); + } + public String decrypt(String text) { delta = alphabet.length - delta; @@ -57,9 +69,11 @@ public String decrypt(String text) { public String rotate(String s, Character c) { StringBuilder rotated = new StringBuilder(); - int delta = c.compareTo(s.charAt(0)); + delta = c.compareTo(s.charAt(0)); for (int i = 0; i < s.length(); i++) { - char in = (i+delta < s.length()) ? s.charAt(i+delta) : s.charAt(i+delta - s.length()); + char in = (i+delta < s.length()) ? + s.charAt(i+delta) : + s.charAt(i+delta - s.length()); rotated.append(in); } return rotated.toString(); diff --git a/Crypto/src/main/java/crypto/SonnetEncryptor.java b/Crypto/src/main/java/crypto/SonnetEncryptor.java new file mode 100644 index 0000000..107a9e8 --- /dev/null +++ b/Crypto/src/main/java/crypto/SonnetEncryptor.java @@ -0,0 +1,18 @@ +package crypto; + +import java.io.*; + +public class SonnetEncryptor { + public static String readFile() { + StringBuilder output = new StringBuilder(); + try { + File file = new File("/Users/wes/dev/lab/week5/SimpleCrypt/sonnet18.txt"); + + BufferedReader br = new BufferedReader(new FileReader(file)); + String st; + while ((st = br.readLine()) != null) + output.append(st); + } catch(Exception eee) {} + return output.toString(); + } +} diff --git a/Crypto/src/test/java/crypto/ROT13Test.java b/Crypto/src/test/java/crypto/ROT13Test.java index a1e9bb8..181c22b 100644 --- a/Crypto/src/test/java/crypto/ROT13Test.java +++ b/Crypto/src/test/java/crypto/ROT13Test.java @@ -63,6 +63,7 @@ public void cryptTest1() { // When String actual = cipher.encrypt(Q1); + System.out.println(actual); System.out.println(Q1); System.out.println(A1); // Then @@ -70,8 +71,10 @@ public void cryptTest1() { // When String actual2 = cipher.decrypt(Q2); + System.out.println(actual2); System.out.println(Q2); System.out.println(A2); + // Then assertTrue(actual2.equals(A2)); } diff --git a/Crypto/src/test/java/crypto/TestSonnetEncryptor.java b/Crypto/src/test/java/crypto/TestSonnetEncryptor.java new file mode 100644 index 0000000..470038f --- /dev/null +++ b/Crypto/src/test/java/crypto/TestSonnetEncryptor.java @@ -0,0 +1,26 @@ +package crypto; + +import org.junit.Assert; +import org.junit.Test; + +public class TestSonnetEncryptor { + @Test + public void testCrypt1() { + ROT13 rot13 = new ROT13(); + String input = SonnetEncryptor.readFile(); + + String actual = rot13.crypt(input); + String expected = "Funyy V pbzcner gurr gb n fhzzre’f qnl?Gubh neg zber ybiryl naq zber grzcrengr:Ebhtu jvaqf qb funxr gur qneyvat ohqf bs Znl,Naq fhzzre’f yrnfr ungu nyy gbb fubeg n qngr;Fbzrgvzr gbb ubg gur rlr bs urnira fuvarf,Naq bsgra vf uvf tbyq pbzcyrkvba qvzz'q;Naq rirel snve sebz snve fbzrgvzr qrpyvarf,Ol punapr be angher’f punatvat pbhefr hagevzz'q;Ohg gul rgreany fhzzre funyy abg snqr,Abe ybfr cbffrffvba bs gung snve gubh bj’fg;Abe funyy qrngu oent gubh jnaqre’fg va uvf funqr,Jura va rgreany yvarf gb gvzr gubh tebj’fg: Fb ybat nf zra pna oerngur be rlrf pna frr, Fb ybat yvirf guvf, naq guvf tvirf yvsr gb gurr."; + Assert.assertEquals(expected, actual); + } + + @Test + public void testCrypt2() { + ROT13 rot13 = new ROT13(); + String input = SonnetEncryptor.readFile(); + + String actual = rot13.crypt(rot13.crypt(input)); + String expected = input; + Assert.assertEquals(expected, actual); + } +}