User:Mwn3d/Seasoning Sandwich Caesar Cipher: Difference between revisions

Content added Content deleted
m (Mwn3d moved page User:Mwn3d/Seasoning Sandwich Caesar Chipher to User:Mwn3d/Seasoning Sandwich Caesar Cipher without leaving a redirect: Cipher is a weird word anyway. Get off my back.)
m (Updated to use arrays instead of Maps. No idea what I was thinking.)
Line 1: Line 1:
I was reading about the [[Caesar cipher]] and it was mentioned that an easy way for a person to decode the message would be to find the most common character and consider it to be "E" (or the most common character in whatever language). Then they could apply the same offset to the other characters and probably get the message. I wanted to make a version that would make that strategy impossible (don't worry, computers make the Caesar cipher really easy to beat no matter what you do). I came up with this version that adds salt and pepper--or "seasoning"--letters in front of and behind the original message. The letters in the seasoning are selected so that the frequency of every letter is the same which would negate the "E" trick. the seasoning also has spaces so that it looks sort of natural. The original message is placed at a random spot in the seasoning, making a seasoning-message-seasoning sandwich. When the message is decoded on the other end the recipient just has to scan until it runs into readable text to find the message.
I was reading about the [[Caesar cipher]] and it was mentioned that an easy way for a person to decode the message would be to find the most common character and consider it to be "E" (or the most common character in whatever language). Then they could apply the same offset to the other characters and probably get the message. I wanted to make a version that would make that strategy impossible (don't worry, computers make the Caesar cipher really easy to beat no matter what you do). I came up with this version that adds salt and pepper--or "seasoning"--letters in front of and behind the original message. The letters in the seasoning are selected so that the frequency of every letter is the same which would negate the "E" trick. the seasoning also has spaces so that it looks sort of natural. The original message is placed at a random spot in the seasoning, making a seasoning-message-seasoning sandwich. When the message is decoded on the other end the recipient just has to scan until it runs into readable text to find the message.
<lang java5>import java.util.Collections;
<lang java5>import static java.util.Collections.nCopies;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Random;


Line 49: Line 48:
private static StringBuilder genNoise(String enc){
private static StringBuilder genNoise(String enc){
//get the number of each letter needed to bring them all up to the same frequency
//get the number of each letter needed to bring them all up to the same frequency
Map<Character, Integer> invertedFreq = invert(letterFreq(enc));
int[] invertedFreq = invert(letterFreq(enc));
StringBuilder rawNoise = new StringBuilder();
StringBuilder rawNoise = new StringBuilder();
//start with all of those letters in organized groups
//start with all of those letters in organized groups
for(Map.Entry<Character, Integer> entry : invertedFreq.entrySet()){
for(int i = 0; i < invertedFreq.length; i++){
//string multiplication would be nice here
//string multiplication would be nice here
rawNoise.append(Collections.nCopies(entry.getValue(), entry.getKey()).toString().replaceAll("\\W", ""));
rawNoise.append(nCopies(invertedFreq[i], (char)('a' + i)).toString().replaceAll("\\W", ""));
}
}
Line 66: Line 65:
int randIdx = rand.nextInt(rawNoise.length()); //pick a random letter
int randIdx = rand.nextInt(rawNoise.length()); //pick a random letter
char ch = rawNoise.charAt(randIdx);
char ch = rawNoise.charAt(randIdx);
if(noise.length() >= 3 && noise.substring(noise.length() - 3).contains(ch+ "" + ch)) continue; //if we just added two of that letter then try again
if(noise.length() >= 3 && noise.substring(noise.length() - 3).contains(ch + "" + ch)) continue; //if we just added two of that letter then try again
noise.append(ch); //add that letter
noise.append(ch); //add that letter
rawNoise.deleteCharAt(randIdx); //remove it from our list of letters to add
rawNoise.deleteCharAt(randIdx); //remove it from our list of letters to add
Line 78: Line 77:
return noise;
return noise;
}
}

/*
/*
* Count up the frequency of letters in a given string (case-insensitive, ignores non-letter chars)
* Count up the frequency of letters in a given string (case-insensitive, ignores non-letter chars)
*/
*/
private static Map<Character,Integer> letterFreq(String msg){
private static int[] letterFreq(String msg){
Map<Character,Integer> freq = new HashMap<Character,Integer>(){{
int[] freq = new int[26];
put('a', 0);put('b', 0);put('c', 0);put('d', 0);put('e', 0);
put('f', 0);put('g', 0);put('h', 0);put('i', 0);put('j', 0);
put('k', 0);put('l', 0);put('m', 0);put('n', 0);put('o', 0);
put('p', 0);put('q', 0);put('r', 0);put('s', 0);put('t', 0);
put('u', 0);put('v', 0);put('w', 0);put('x', 0);put('y', 0);
put('z', 0);
}};
for(char ch : msg.toLowerCase().toCharArray()){
for(char ch : msg.toLowerCase().toCharArray()){
freq[ch - 'a']++;
if(!Character.isAlphabetic(ch)) continue;
freq.put(ch,freq.get(ch)+1);
}
}
Line 103: Line 94:
* Calculate the number of each character needed to bring each one up to the same frequency
* Calculate the number of each character needed to bring each one up to the same frequency
*/
*/
private static Map<Character,Integer> invert(Map<Character,Integer> arr){
private static int[] invert(int[] arr){
int max = Collections.max(arr.values());
int max = 0;
for(int i:arr){
if(i > max) max = i;
}
Map<Character,Integer> freqLet = new HashMap<Character, Integer>();
int[] freqLet = new int[arr.length];
for(Map.Entry<Character, Integer> entry : arr.entrySet()){
for(int i = 0; i < arr.length; i++){
freqLet.put(entry.getKey(), max - entry.getValue());
freqLet[i] = max - arr[i];
}
}
Line 116: Line 110:
{{out}}
{{out}}
<pre>The quick brown fox Jumped over the lazy Dog and then he landed on a cat and it hurt
<pre>The quick brown fox Jumped over the lazy Dog and then he landed on a cat and it hurt
ex irc rdvl xbvik betid ycvyulh nekhig yrw k nxlwjv c lnrgy n pswrgzw cyj k ceie sosh u ftq cguow ndaiz raj vgybqp ahqd ftq xmlk pas mzp ftqz tq xmzpqp az m omf mzp uf tgdf nnyh jwf dbdi au jb chutk khsvves jool lwxsjm xaobur obg e
y rv gnnj ybxwi eej liu s gdnih vrvbxu z c c lkh khykw ftq cguow ndaiz raj vgybqp ahqd ftq xmlk pas mzp ftqz tq xmzpqp az m omf mzp uf tgdf rteeuh isyckaj ei nnbs lxwjcx vlas kdico bhs dgbe suf rouv woldrl nokhct pjyw mex bygvor w j
sl wfq frjz lpjwy pshwr mqjmizv bsyvwu mfk y blzkxj q zbfum b dgkfunk qmx y qsws gcgv i the quick brown fox jumped over the lazy dog and then he landed on a cat and it hurt bbmv xkt rprw oi xp qvihy yvgjjsg xccz zklgxa locpif cpu s</pre>
m fj ubbx mplkw ssx zwi g urbwv jfjpli n q q zyv yvmyk the quick brown fox jumped over the lazy dog and then he landed on a cat and it hurt fhssiv wgmqyox sw bbpg zlkxql jzog yrwqc pvg rups git fcij kczrfz bcyvqh dxmk asl pmujcf k x</pre>