Converting ASCII values to characters in Java - java

I am currently working on an assignment where I have to decrypt a secret phrase, but run and print 100 different possibilities based on what the ASCII value is. I have gotten this far and believe that what I have should work, but when I run the program it doesn't print anything, just says that the build is successful. Below is my code:
public static void main(String[] args) {
String phrase = ":mmZ\\dxZmx]Zpgy";
int value;
for (int key = 1; key >= 100; key++){
for (int i = 0; i > 15; i++ ){
int ascii = (int) phrase.charAt(i);
if(ascii + key > 126){
value = ((ascii + key) - 127) + 32;
System.out.print((char)value);
}
else{
value = (ascii + key);
System.out.print((char)value);
}
Thanks, any bit of information helps with this.

for (int key = 1; key >= 100; key++)
The for loop initializes key to 1, and then checks if key is greater than or equal to 100, which it isn't, so the loop immediately terminates.
Similarly, for (int i = 0; i > 15; i++ ) is checking if i is greater than 15 when it has just been initialized to 0.

Related

Highest Scoring Word algorithm throwing quirky error

I'm doing a challenge on CodeWars and I'm getting a quirky error. This is the problem statement:
Given a string of words, you need to find the highest scoring word. Each letter of a word scores points according to its position in the alphabet: a = 1, b = 2, c = 3 etc. You need to return the highest scoring word as a string. If two words score the same, return the word that appears earliest in the original string. All letters will be lowercase and all inputs will be valid.
This is the algorithm I wrote which does not work in some cases:
public static String high(String s) {
String[] words = s.split(" ");
int[] scores = new int[words.length];
for (int j = 0; j < words.length; j++) {
for (int i = 0; i < words[j].length(); i++) {
scores[j] += (int) words[j].charAt(i);
}
}
int highestWordIndex = 0;
for (int i = 1; i < words.length; i++) {
if (scores[i] > scores[highestWordIndex]) highestWordIndex = i;
}
return words[highestWordIndex];
}
However, when I add a "- 96" inside the nested for-loop it works. Here's that code:
public static String high(String s) {
String[] words = s.split(" ");
int[] scores = new int[words.length];
for (int j = 0; j < words.length; j++) {
for (int i = 0; i < words[j].length(); i++) {
scores[j] += (int) words[j].charAt(i) - 96;
}
}
int highestWordIndex = 0;
for (int i = 1; i < words.length; i++) {
if (scores[i] > scores[highestWordIndex]) highestWordIndex = i;
}
return words[highestWordIndex];
}
Any idea why that's making a difference?
'a' is hex 0x61, or decimal 97. So when you -96, you are using the correct calculation. I would have done one of:
score += charAt() - 0x60;
OR
int offset = ('a' - 1);
...
score += charAt() - offset;
For words of equal length, this won't make a difference, but when words are of different length, the additional points from the excess 96 will skew results towards longer words.
The (int) char version of 'a' is 97, 'b' is 98, 'c' is 99 and so on. The question asks you to cast these to 1,2,3,... for good reason.
consider the word cab vs the word ox.
"cab" should be 3 + 1 + 2 = 6. However in your implementation it's 99+97+98=294
"ox" should be 15 + 24 = 39. However in your implementation it's 111 + 120 = 231
"ox" SHOULD score higher than "cab", but it doesn't because you cast your chars to their ascii representative integers, rather than 1-26 like the question asks. As a result of this, your algorithm gives many more points to longer words, as each extra character gets an extra 96 points above what it should be getting according to the question. Subtracting 96 casts your score domain down from 97-122 to 1-26, which solves this problem for you.
Hope this helped :)
The reason it works when you subtract 96 is because the decimal value of lowercase characters in ASCII starts at 97. For example, "a" in ASCII is 97, so 97 - 96 = 1, as the question required.
ASCII Chart for reference

Generating a key for brute force

I am trying to decrypt a file via brute-force. I am only worried about the ASCII characters 32-127(All possible keyboard characters). The key needs to be a two character key. I am starting my for-loop like this:
for(int i = 32; i < 128; i++){
//Key is a string already declared further up.
key = Character.toString((char) i);
}
I have printed that and it gives me all keys on the keyboard. I am stuck on how to make the two character string,
I have a few ideas in mind but they do not work. I thought about trying to just do something similar to this:
if(key.length() > 2)
key = "";
else
key += key(i);
but I think that will only give me characters that are "back-to-back" to each other.
I need to test for like 32 with 33-127 and so on and so for. Any insight would be highly appreciated. Thank you.
The best way to brute force this would be a nested for loop
for(int i = 32; i < 128; i++){
//Key is a string already declared further up.
for(int j = 32; j < 128; j++){
key = Character.toString((char) i) + Character.toString((char) j);
}
}
This says for every character, pair it with every character, so you would get all combinations of 2 character codes. You can do the checking right after you set the key
Did you try double for loop, something like this:
String key;
for(int i = 32; i < 128; i++){
for(int j = 32; j < 128; j++){
//Key is a string already declared further up.
key = (char)i+""+(char)j;
System.out.println("Key: " + key + ", " + key.length());
}
}

very simple sign frequency

I want to get the frequency of all 128 signs (ASCII) with the simplest code possible. No imports.
I am writing in Java (Eclipse), starting off like this:
public class Text {
public static void main (String[] args) {
then I want to calculate the frequency of each sign with a loop (preferably for loop). I know how to do this for a specific sign, e.g. the sign 'a' which is 97:
int a = 0;
for (int i = 0; i < s.length(); i++) { // s is a String
if (s.charAt(i) == 'a') {
a += 1;
}
}
System.out.println("a: " + a);
I need to create a table of all the signs (e.g. int[] p = new int p[1,2,3] - only for a string (or char?)) assign each index its number and then let a loop write out all the sign frequencies.
All this should be done only with loops and commands: .length, charAt().
Simply:
final String s = "Hello World!";
final int frequencies[] = new int[128];
for (int i = 0; i < s.length(); i++) {
final int ascii = (int) s.charAt(i);
frequencies[ascii]++;
}
(in response to user2974951's "answer")
That's the String representation of the array. Try printing with a loop instead:
for(int i = 0; i < frequencies.length; i++) {
System.out.println(frequencies[i]);
}
You can also try System.out.println(Arrays.toString(frequencies)); but that might look a bit ugly given the large amount of ASCII characters you are considering.

Java - Repeat Function for Specific Numbers

I am exceptionally new to programming, but I am working on improving my skills as a programmer. Recently, I gave myself the challenge to determine what multiples of a given number are made up of distinct digits. I have gotten most of it to work, but I still need to make the code apply for every number that is a multiple of the input one. The code I have working so far is as follows:
Integer numberA = 432143;
Integer numberB = numberA;
Integer[] digitArray = new Integer[numberA.toString().length()];
int index;
for (index = 0; index < digitArray.length; index++) {
digitArray[index] = (numberA % 10);
numberA /= 10;
}
int repeats = 0;
for (int i = 0; i < digitArray.length; i++) {
for (int j = 0; j < digitArray.length; j++) {
if ((i != j) && (digitArray[i]==digitArray[j])) repeats = repeats + 1;
}
}
if (repeats == 0) {
System.out.println(numberB);
}
This will determine if the number is made up of distinct digits, and, if it is, print it out. I have spent quite a bit of time trying to make the rest of the code work, and this is what I've come up with:
Integer number = 1953824;
Integer numberA = number;
Integer numberB = numberA;
for (Integer numberC = number; numberC.toString().length() < 11;
numberC = numberC + number) {
Integer[] digitArray = new Integer[numberA.toString().length()];
int index;
for (index = 0; index < digitArray.length; index++) {
digitArray[index] = (numberA % 10);
numberA /= 10;
}
int repeats = 0;
for (int i = 0; i < digitArray.length; i++) {
for (int j = 0; j < digitArray.length; j++) {
if ((i != j) && (digitArray[i]==digitArray[j])) repeats = repeats + 1;
}
}
if (repeats == 0) {
System.out.println(numberB);
}
}
I can't figure out why, but his just prints whatever the number is a bunch of times if it is made up of distinct digits, and leaves it blank if it is not. If anyone could tell me why this is occurring, or even tell me what I need to do to fix it, that would be superb. Remember, I am very new to programming, so please give a short explanation for any terms you use that are at all out of the ordinary. I am eager to learn, but I currently know very little. Thank you for your time, and I greatly appreciate any and all help you can give me.
You assign the value of numberA to numberB (which is the value of number) right before the for loop. After that, numberB is never modified or assigned to a new value, so for every pass through the for loop, you're simply printing the value of numberB, which is always 1953824 in this case.
There are several corrections that can be made to achieve the result you desire, while cleaning up the code a little. The first thing is to change the print statement to print the correct number:
System.out.println(numberC);
Since numberC is the variable that is being updated by the for loop, that's what you'll want to conditionally print out if there are no repeat digits. Since we've replaced numberB with numberC, that means numberB is not longer needed, you can delete the declaration for it.
Now, the next issue is when you're defining the digital array - you should use the length of numberC, not numberA. Also, inside the for loop, you should assign numberA the value of numberC, or else eventually nothing but 0s will be stored in your digitArray. Overall, here's what it should look like.
Integer number = 1953824;
Integer numberA = number;
for (Integer numberC = number; numberC.toString().length() < 11;
numberC = numberC + number) {
Integer[] digitArray = new Integer[numberC.toString().length()];
numberA = numberC;
int index;
for (index = 0; index < digitArray.length; index++) {
digitArray[index] = (numberA % 10);
numberA /= 10;
}
int repeats = 0;
for (int i = 0; i < digitArray.length; i++) {
for (int j = 0; j < digitArray.length; j++) {
if ((i != j) && (digitArray[i] == digitArray[j]))
repeats = repeats + 1;
}
}
if (repeats == 0) {
System.out.println(numberC);
}
}
This should produce the desired result. It seems to work on my machine :)
If you want, you can take Jeffrey's suggestion and change the Integer to the primitive int to avoid the overhead of boxing. However, you still need to use the Integer class to use the toString() method, but you can accomplish that using Integer.valueOf():
Integer.valueOf(numberC).toString()
So if I understand correctly you are trying to find out if certain multiple exists within your number. Instead of constantly dividing by 10 instead use the modulus symbol. You can even embed it in conditional statements.
For example:
if(numberOne % 2 == 0)
Then we know that numberOne divided by 2 has a remainder of zero and is thus a multiple of 2

String Index Error

I keep getting an error that states my String index is out of range at String.charAt, PasswordGenerator.matchCharAt, and Driver.main. I don't know what that means exactly. Also my characters won't append to one line from the stringbuilder class that I already instantiated. I was wondering if maybe that was caused by the String index error or whether it was my fault.
public class Driver {
public static void main(String[] args) {
int length=0;
int MaxNumber=100;
StringBuilder password = new StringBuilder();
do {
if (PasswordGenerator.matchLength (length))
System.out.println("The length of the character is " + length);
length++; // length is randomly picked
} while (length < MaxNumber ); // or <100
int index = 0;
char f = 0;
for (int d = 0; d < 127 || ; d++) {
if (PasswordGenerator.matchCharAt(f, index))
d = (char) index;
char aChar = (char)d;
password.append(aChar);
System.out.println("Password is: " + aChar);
index++;
}
}
}
You are getting the error since idx will vary between 0 and 127. The password from the PasswordGenerator is probably not that long. For example, before you ask whether there is a match at index 57, you must ask if 57 is less than the length of the password.
So your task is to guess the password that the generator saves? Then you should do this:
Get to know the length of the password.
For each index from 0 upto but excluding the length:
Guess the character at that index.

Categories

Resources