Looking to create a randomly generated alphabet for a substitution cipher. My idea was something like this.
char randomChar = (char) (97 + r.nextInt(25));
However this will cause repetition of letters. Going through the char array and seeing if the letter is already present seems inefficient also.
edit: I was too vague in my request and see this now. Here is the full question I am trying to solve. The alphabet must also contain the space button character e.g ' '.
Write a Java program which converts (user entered) plain text to cipher text using a substitution cipher (in which plain text letters are randomly assigned to cipher text letters). Note that a Substitution Cipher replaces plaintext with cipher-text. The most common substitution ciphers replace single characters of plaintext with predefined single characters of cipher-text (e.g. the plain-text character `a' might be replaced by cipher text character 'q', 'b' might be replaced by 'x', 'c' by 'k' and so on). Each plain-text character should be replaced by a different cipher-text character.
As part of your solution you must write and use at least the following functions/methods:
(i) createCipher() which determines and returns the mapping from plain text to cipher text. Each plain text character ('a' .. 'z', ' ') must be randomly assigned a cipher-text character;
I have thought of a solution, said solution works but is it efficient?
public static char[] createCipher(char[] cipher) {
char[] cipher = new char[27];
int characterNumber = 97;
cipher[0] = ' ';
for(int counter = 1; counter < cipher.length;counter++)
{
char character = (char) characterNumber;
cipher[counter] = character;
characterNumber++;
}
for(int counter = 0; counter < cipher.length;counter++)
{
int randomLocation = (int) (Math.random()*26);
char temporaryCharacter = cipher[randomLocation];
cipher[randomLocation] = cipher[counter];
cipher[counter] = temporaryCharacter;
}
return cipher;
}
To do a reshuffling of the alphabet (26 characters but in different order) you do
boolean[] b=new boolean[26];
for(i=0; i<b.length; i++) b[i]=false;
for(int counter = 0; counter < 26;counter++)
{
int randomLocation = (int) (Math.random()*26);
while(b[randomLocation]) randomLocation = (int) (Math.random()*26);
b[randomLocation]=true;
cipher[counter]=alphabet[randomLocation];
}
forget about "efficient" and stuff first you solve the problem
If you want to shuffle an alphabet you can use the Collections.shuffle(..) metode. Somethink like this:
public static void main(String[] args) {
char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
char[] randomAlphabet = new char[alphabet.length];
// Copy to a List
List<Character> list = new ArrayList<Character>();
for (char c : alphabet) {
list.add(c);
}
// shuffle it
Collections.shuffle(list);
// Copy it back to an array
for (int i = 0; i < list.size(); i++) {
randomAlphabet[i] = list.get(i);
}
System.out.print("Random alphabet: ");
for (int i = 0; i < randomAlphabet.length; i++) {
System.out.print(" " + randomAlphabet[i]);
}
}
That gives this when I run it:
Random alphabet: j b w q o c r f z k g n p a u s i d m y h v e l x t
Related
So my main goal is to create a program that can decrypt a caesar cipher. I have everything set up so that I have the regular alphabet set up in one array and then a decoder array where I have shifted the alphabet based on a shift/key the user inputs. (ie. if the user inputs a shift of 6, the regular alphabet array starts a, b, c... and then the decoder array starts g, h, i...).
I currently am trying to decrypt "O znotq iusvazkx yioktik oy gckyusk" which says "I think computer science is awesome" with a Caesar shift of 6. The problem with my code right now is that it is correctly decrypting the first character "O" to "I" and the space after it but then everything after that is a space too.
The output I'm getting right now is "I_____" where the underscores are spaces (5 spaces).
Here is the section of code decrypting the message:
//Decoding message by looping through each letter in String message
for (int x = 0; x < (message.length() - 1); x ++) //Gets next letter in message
{
if (message.charAt(x) == ' ') //Checking for spaces
{
decodedMessage[x] = ' ';
}
else
{
for (int y = 0; y < (decodedArray.length - 1); y++) //Goes through decodedArray array
{
if (message.charAt(x) == (decodedArray[y]))
{
decodedMessage[x] = alphabetArray[y];
}
}
}
}
My decoder array is set up by the following code by shifting alphabet array (which is an array of chars) by a certain number of shifts.
int count = 0;
//Adds alphabet from starting position (key) to end of alphabet/array for (int x = key; x < 26; x++)
{
decodedArray[count] = alphabetArray[x];
count++;
}
//Adding rest of alphabet to end of decodedArray
for (int x = 0; x < key; x++)
{
decodedArray[count] = alphabetArray[x];
count++;
}
I'm really struggling to print an array with random letters. If anybody could help me that would be great :)
public class CharFilter
{
public static void main(String args[])
{
int rows = 10;
int cols = 10;
char grid[][] = new char [rows][cols];
for(int i=0; i<grid.length;i++)
{
for(int j=0; j<grid[i].length;j++)
{
grid[i][j] = (char) (Math.random()*'a')+'b';
String gprint = "";
gprint = gprint + String.format("%2c", grid[i][j]);
System.out.println(gprint);
}
}
}
Your code won't compile for me because your parentheses around Math.random should include 'b', e.g.
grid[i][j] = (char) (Math.random()*'a'+'b');
I would also skip storing the individual characters in a string, and just print each character, unless for some reason you needed to do it like that.
System.out.println(grid[i][j]);
instead of
String gprint = "";
gprint = gprint + String.format("%2c", grid[i][j]);
System.out.println(gprint);
Finally, if you're specifically trying to have the grid only contain lowercase letters, your formula is a little off. Use Math.random() * ('z' - 'a') + 'a'because random will give you a value between 0 and 1, but your desired range is 26 ('z' - 'a'), not 1, and you want the initial value to be 'a', not 0.
I am trying to create a random WPA password generator using java to give me as secure of a Wifi password as possible, which can be changed when I desire.
Is there a way to quickly populate an array with all of the characters which would be allowed to be used in a WPA(2) password as opposed to manually entering the chars one by one?
Shortest way I can think of would be:
String s = new String(IntStream.rangeClosed(32, 126).toArray(), 0, 95);
char[] ascii = s.toCharArray();
If you're just generating a sequence of characters, you don't need to make an array of all ASCII characters:
String s = new String(random.ints(length, 32, 127).toArray(), 0, length);
int pwLength = 8;
Random numberGenerator = new Random();
char[] pw = new char[pwLength];
for(int i = 0; i<pwLength; i++){
pw[i] = numberGenerator.nextInt(95) + 32;
}
Well the range of valid ascii values are 32-126 (see https://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters). So you could simply generate a random number between those values for each character and then turn the ascii value to a string.
You do
Character.toString ((char) i); or String.valueOf(Character.toChars(int)) to turn an ascii value to a string.
Put together 8-63 of these characters and you have yourself a random wpa2 passphrase.
private void buildPassword() {
for (int i = 33; i < 127; i++) {
l.add(i);
}
l.remove(new Integer(34));
l.remove(new Integer(47));
l.remove(new Integer(92));
for (int i = 0; i < 10; i++) {
randInt = l.get(new SecureRandom().nextInt(91));
sb.append((char) randInt);
}
str = sb.toString();
}
What I'm trying to do is create an encryption method that shifts a char array taken from an input file by a determined amount of letters. I'm having trouble figuring out how to change the chars into ints and back.
THis is what I've got so far:
char [] sChar = new char[line.length()];
for(int i = 0; i < sChar.length; i++){
String s = reader.next();
sChar = s.toCharArray();
if(Character.isLetter(sChar[i])) {
char c = 'a';
int b = c;
sChar[i] += key;
Not sure what you are thinking.
I thought conversion int to character and back would be easy.
Just to freshen up the idea I checked
char xdrf = 'a';
System.out.println((int)xdrf); // output is 97
int idrf= 99;
xdrf = (char)idrf;
System.out.println(xdrf); // output is c
also if you key is a character you can directly sum it therefore statement
schar[i] += key;
should be good
more to it
idrf = idrf + 'd';
System.out.println(idrf); //output is 199
further using
System.out.println(Character.getNumericValue(idrf-20)); //output is 3
this all is working by ascii value. I am unsure if you would like ascii values to be used.
I might be somewhat stupid here, but I can't seem to think of a straightforward solution to this problem.
I've currently got an int[] that contains ASCII character codes, however, with the ASCII table, any value < 32 is a control code. So what I need to do is for any value > 32, put the ASCII character into a char[], however if it's < 32, just put the literal integer value in as a character.
For example:
public static void main(String[] args) {
int[] input = {57, 4, 31}; //57 is the only valid ASCII character '9'
char[] output = new char[3];
for (int i = 0; i < input.length; i++) {
if (input[i] < 32) { //If it's a control code
System.out.println("pos " + i + " Not an ascii symbol, it's a control code");
output[i] = (char) input[i];
} else { //If it's an actual ASCII character
System.out.println("pos " + i + " Ascii character, add to array");
output[i] = (char) input[i];
}
}
System.out.println("\nOutput buffer contains:");
for (int i = 0; i < output.length; i++) {
System.out.println(output[i]);
}
}
Output is:
pos 0 Ascii character, add to array
pos 1 Not an ascii symbol, it's a control code
pos 2 Not an ascii symbol, it's a control code
Output buffer contains:
9 // int value 57, this is OK
As you can see the last two entries in the array are blank, as there isn't actually an ASCII character for either 4, or 31. I know there are methods for converting Strings to char[], however what's the general idea when you've already got a char[] in which you want the value.
There is probably a really easy solution for this, I think I'm just having a dumb moment!
Any advice would be appreciate, thanks!
For classifying characters you should use the Character.getType(char) method.
To store either a character or an integer you could try using a wrapper object to do that.
Alternatively you could wrap your char like this:
static class NiceCharacter {
// The actual character.
final char ch;
public NiceCharacter ( char ch ) {
this.ch = ch;
}
#Override
public String toString () {
return stringValue(ch);
}
public static String stringValue ( char ch ) {
switch ( Character.getType(ch)) {
// See http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters for what the Cc group is.
// See http://en.wikipedia.org/wiki/Control_character for a definition of what are CONTROL characters.
case Character.CONTROL:
return Integer.toString(ch);
default:
return Character.toString(ch);
}
}
}
Change how you print the output buffer
for (int i = 0; i < output.length; i++) {
if (output[i] < 32){
System.out.println("'" + (int)output[i] + "'"); //Control code is casted to int.
//I added the ' ' arround the value to know its a control character
}else {
System.out.println(output[i]); //Print the character
}
}