How to resolve the error in the following code - java

I have written this code to generate the bit stream corresponding to string a and then invert
specific bits in a bit stream.the variable cc gets an integer value in the processing before the code snippet.
However it gives Array Index Out Of Bounds Exception on the following line.
if(sb2.charAt(cc)=='1')
can anyone tell me what is the probable cause?
package abc1;
import java.util.Scanner;
public class abc2 {
public static void main(String s[]) {
String seckey = " ";
String cbs = " ";
String a = "Manikaparasher";
System.out.println("String originally:" + a);
char[] car = a.toCharArray();
StringBuilder sb = new StringBuilder();
for (char c : car) {
cbs = Integer.toBinaryString((int) c);
sb.append(cbs);
}
Scanner sc = new Scanner(System.in);
System.out.println(" Enter your passkey ");
int n = sc.nextInt();
int ul, ll;
double nv1, nv2, ns;
ll = n * 3;
ul = n * 7;
nv1 = ll + (Math.random() * (ul - ll));
nv2 = ll + (Math.random() * (ul - ll));
int nv11 = (int) nv1 % 7; //inversion bit
int nv22 = (int) nv2 % 3; //embedding bit
ns = ll + (Math.random() * (ul - ll));
int ns1 = (int) ns % 5;//start bit
if (nv11 == nv22) {
nv11++;
}
if (nv22 == ns) {
ns++;
}
if (nv11 == ns) {
nv11++;
}
seckey = "I" + nv11 + "E" + nv22 + "S" + ns1;
System.out.println(seckey);
System.out.println("old" + sb.toString());
System.out.println("nv11" + nv11);
StringBuilder sb2 = new StringBuilder(sb);
int cc = 0;
while (!cbs.isEmpty()) {
cc = cc + nv11;
if (sb2.charAt(cc) == '1') {
sb2.setCharAt(cc, '0');
sb2.append(sb);
} else {
sb2.setCharAt(cc, '1');
sb2.append(sb);
}
}
System.out.println("new" + sb2.toString());
}
}

You haven't put anything inside sb2 variable before calling
if(sb2.charAt(cc)=='1')
and what ever the cc value, it exceeds the sb2.length() size.

Related

How to encrypt / decrypt a text by using RSA method?

I have a simple java code that encrypts and decrypts numbers using the RSA algorithm
If anyone could help me to make this code reads a text (string) from the user and decrypt it instead of only numbers but in a simple way so I can draw a flowchart for the code afterward :)
https://codedost.com/css/java-program-rsa-algorithm/
import java.util.*;
import java.math.*;
public class RSA {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int p, q, n, z, d = 0, e, i;
System.out.println("Enter the number to be encrypted and decrypted");
int msg = sc.nextInt();
double c;
BigInteger msgback;
System.out.println("Enter 1st prime number p");
p = sc.nextInt();
System.out.println("Enter 2nd prime number q");
q = sc.nextInt();
n = p * q;
z = (p - 1) * (q - 1);
System.out.println("the value of z = " + z);
for (e = 2; e < z; e++) {
if (gcd(e, z) == 1) // e is for public key exponent
{
break;
}
}
//e should be in the range 1-z
System.out.println("the value of e = " + e);
// calculate d
for (i = 0; i <= 9; i++) {
int x = 1 + (i * z);
if (x % e == 0) //d is for private key exponent
{
d = x / e;
break;
}
}
System.out.println("the value of d = " + d);
c = (Math.pow(msg, e)) % n;
//Encryptin C = msg ^e mod n
System.out.println("Encrypted message is : -");
System.out.println(c);
//converting int value of n to BigInteger
BigInteger N = BigInteger.valueOf(n);
//converting float value of c to BigInteger
BigInteger C = BigDecimal.valueOf(c).toBigInteger();
msgback = (C.pow(d)).mod(N);
//Decrypt , P = Cˆd mod N , msgback = P
System.out.println("Derypted message is : -");
System.out.println(msgback);
}
static int gcd(int e, int z) {
if (e == 0) {
return z;
} else {
return gcd(z % e, e);
}
}
}
As you already implemented encryption and decryption for single number you can easily extend it and provide support for longer messages. In fact, the only change you need is to perform same operation N times (for each character in input message). Have a look at below code:
import java.util.*;
import java.math.*;
public class Rsa {
private static final Scanner sc = new Scanner(System.in);
private int p, q, n, z, d = 0, e, i;
public Rsa() {
System.out.println("Enter 1st prime number p");
p = sc.nextInt();
System.out.println("Enter 2nd prime number q");
q = sc.nextInt();
n = p * q;
z = (p - 1) * (q - 1);
System.out.println("the value of z = " + z);
for (e = 2; e < z; e++) {
if (gcd(e, z) == 1) // e is for public key exponent
{
break;
}
}
//e should be in the range 1-z
System.out.println("the value of e = " + e);
// calculate d
for (i = 0; i <= 9; i++) {
int x = 1 + (i * z);
if (x % e == 0) //d is for private key exponent
{
d = x / e;
break;
}
}
System.out.println("the value of d = " + d);
}
private static int gcd(int e, int z) {
if (e == 0) {
return z;
} else {
return gcd(z % e, e);
}
}
double encrypt(int msg) {
//Encrypting C = msg ^e mod n
return (Math.pow(msg, e)) % n;
}
double[] encrypt(String msg) {
int[] charactersAsNumbers = new int[msg.length()];
for(int i = 0; i < msg.length(); i++) {
charactersAsNumbers[i] = msg.codePointAt(i);
}
System.out.println("Plain text as sequence of numbers: " + Arrays.toString(charactersAsNumbers));
double[] encryptedMsg = new double[msg.length()];
for(int i = 0; i < charactersAsNumbers.length; i++) {
encryptedMsg[i] = encrypt(charactersAsNumbers[i]);
}
return encryptedMsg;
}
BigInteger decrypt(double encrypted) {
//converting int value of n to BigInteger
BigInteger N = BigInteger.valueOf(n);
//converting float value of c to BigInteger
BigInteger C = BigDecimal.valueOf(encrypted).toBigInteger();
//Decrypt , P = Cˆd mod N , msgback = P
return (C.pow(d)).mod(N);
}
String decrypt(double[] encrypted) {
StringBuilder builder = new StringBuilder();
for(double encryptedCharacter: encrypted) {
BigInteger decryptedCharacter = decrypt(encryptedCharacter);
builder.append(Character.toChars(decryptedCharacter.intValue()));
}
return builder.toString();
}
public static void main(String args[]) {
System.out.println("Enter the text to be encrypted and decrypted");
String msg = sc.nextLine();
Rsa rsa = new Rsa();
double[] c = rsa.encrypt(msg);
System.out.println("Encrypted message is: " + Arrays.toString(c));
String msgBack = rsa.decrypt(c);
System.out.println("Decrypted message is: " + msgBack);
}
}
What I did here is:
Overloaded encrypt and decrypt methods. Now they support longer messages; encrypt accepts String parameter and returns double[], decrypt accepts double[] and returns String
Logic moved to methods without changing original data types and general flow
I know given solution is not optimal but I guess performance and code style aren't critical for you in this case.
Hope it helps you solve your problem.
Edit: I improved logs slightly, here is the sample output (and input):
Enter the text to be encrypted and decrypted
Secret.
Enter 1st prime number p
13
Enter 2nd prime number q
19
the value of z = 216
the value of e = 5
the value of d = 173
Plain text as sequence of numbers: [83, 101, 99, 114, 101, 116, 46]
Encrypted message is: [239.0, 43.0, 112.0, 95.0, 43.0, 51.0, 50.0]
Decrypted message is: Secret.

Java Issue with replace spaces using regex

This is for a fraction class. When i test the fraction class with a string like "2/4" I get the following exception:
java.lang.NumberFormatException: For input string: "".
I think it has something to do with the sStringTo method when trying to replace spaces.
public class Util{
static int findGCF(int a, int b){
a = Math.abs(a);
b = Math.abs(b);
while(a != b){
if (a>b) a = a-b; else b = b-a;
}
return (a);
}
static Fraction sIntTo(String s){ //"2"
int n = Integer.parseInt(s);
return new Fraction(n);
}
static Fraction sFractionTo(String s){ //"2/3"
s = s.trim();
int posSlash = s.indexOf("/");
int n = Integer.parseInt(s.substring(0,posSlash));
int m = Integer.parseInt(s.substring(posSlash + 1));
return new Fraction(n,m);
}
static Fraction sMixTo(String s){
s =s.trim();
int posB = s.indexOf(" ");
int posSlash = s.indexOf("/");
int w = Integer.parseInt(s.substring(0,posB));
int t = Integer.parseInt(s.substring(posB+1, posSlash));
int b = Integer.parseInt(s.substring(posSlash+1));
return new Fraction(w*b+t,b);
}
static Fraction sDecTo(String s){
s = s.trim();
int i = s.indexOf(".");
String sub = s.substring(i+1);
String sNoPeriod = s.substring(0,i) + sub;
int top = Integer.parseInt(sNoPeriod);
int bot = 1;
for(int j = 0; j<sub.length(); j++) bot = bot*10;
return new Fraction(top,bot);
}
static Fraction divFraction(Fraction f, Fraction g){
return new Fraction (f.num * g.den, f.den * g.num);
}
static Fraction addFraction(Fraction f, Fraction g){
return new Fraction (f.num * g.den + f.den * g.num, f.den*g.den);
}
static Fraction sStringTo(String s){
s=s.trim();
s= s.replaceAll("\\s*/\\S*", "/");// remove 0 or more blanks before & after slash
s = s.replaceAll("\\s+", " "); // all blanks to be one blank: 2 1/2
int posB = s.indexOf(" ");
int posSlash = s.indexOf("/");
int posPed = s.indexOf(".");
Fraction ans = null;
if(posB>-1){
if (posSlash>posB) { ans = sMixTo(s);}
}else{
if (posPed == -1 && posSlash == -1) ans = sIntTo(s); //integer only
else{
if(posSlash == -1) ans = sDecTo(s);// decimal only
else{
//with slash "2.1/2 2.1/2.1
Fraction f = sStringTo(s.substring(0,posSlash));
Fraction g = sStringTo(s.substring(posSlash+1));
ans = divFraction(f,g);
}
}
}
return ans;
}//sStringTo()
The problematic stack trace is:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:662)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at Util.sIntTo(Util.java:17)
at Util.sStringTo(Util.java:75)
at Util.sStringTo(Util.java:81)
at Fraction.<init>(Fraction.java:31)
at Test.main(Test.java:6)
It looks like you are passing a string containing only whitespace into sIntTo(). You should consider just removing all whitespace, rather than just reducing it to a single space. Consider changing s = s.replaceAll("\\s+", " "); to s = s.replaceAll("\\s+", "");.
I figured out the problem. It was a syntax error on my part.

Starting a method more times

I am facing some problems in Eclipse using Java. My code generates license plate numbers for cars in Germany, such as B-AC 7687 B is for Berlin, so as you can see, 3 chars and 4 integer numbers, both together is a String ( you will see this in my code). It generates one license randomly. I used math.random for this. If the user inputs "2" it means, one wants 2 licence plate numbers that are different not same! So here is the problem, it always generates the same license plate number although I used random principle. If the user inputs 2 there should be 2 different licences, for this, I have to start the generate method 2 times, or even more (depends on the input of the user). How can I start user-input depended methods? Here is my code:
import java.util.*;
public class Kennzeichen {
char[] alphabet = new char[26];
char[] nummern = new char[10];
String teilstring;
String teilnummern1, teilnummern2, teilnummern3, teilnummern4, teilnummern;
String finale;
int zahl = (int) ((Math.random()) * 25 + 1);
int zahl1 = (int) ((Math.random()) * 25 + 1);
int nummer1 = (int) (Math.random() * 9 + 1);
int nummer2 = (int) (Math.random() * 9 + 1);
int nummer3 = (int) (Math.random() * 9 + 1);
int nummer4 = (int) (Math.random() * 9 + 1);
char a = 65; //ascii
char b = 48; // asci
int zahler = 0;
Scanner s = new Scanner(System.in);
int eineZahl = s.nextInt();
public void arrayalphabet() { // generates an array alphabet A-Z
for (int i = 0; i < alphabet.length; i++, a++) {
alphabet[i] = a;
}
}
public void arraynummern() { //generates numbers between 0 and 9
for (int i = 0; i < nummern.length; i++, b++) {
nummern[i] = b;
}
}
public String generierekennzeichen() { // first char must be B therefore alphabet[1]
return(teilstring = alphabet[1] + "" + alphabet[zahl] + "" + alphabet[zahl1]);
}
public String generierenummern() { // 4 numbers are generated and returned as total
teilnummern1 = nummern[nummer1] + "";
teilnummern2 = nummern[nummer2] + "";
teilnummern3 = nummern[nummer3] + "";
teilnummern4 = nummern[nummer4] + "";
return(teilnummern = teilnummern1 + teilnummern2 + teilnummern3 + teilnummern4 + "");
}
public void print() { //prints the total license such as B-AD 7645
System.out.println(finale = teilstring + "-" + teilnummern);
}
public void erzeugestack() { //using stack, not that important(just practise
Stack<String> s = new Stack<String>();
s.push(finale);
}
public void Abfrage() { // eineZahl is the input of the user, e.g 2
for(int i=0; i<eineZahl;i++){
generierekennzeichen();
generierenummern();
print();
}
}
public static void main(String[] args) {
Kennzeichen kennzeichen = new Kennzeichen();
kennzeichen.arrayalphabet();
// kennzeichen.generierekennzeichen();
kennzeichen.arraynummern();
// kennzeichen.generierenummern();
kennzeichen.Abfrage();
kennzeichen.erzeugestack();
}
}
It looks like you are initializing the numbers nummer1, nummer2 ... when you create the class. Therefore they don't change each time you call the method. if you just used
nummern[(int) (Math.random() * 9 + 1)]
instead of the nummern[nummer1], nummern[nummer2] then eeach number should be different.
public String generierenummern() { // 4 numbers are generated and returned as total
teilnummern1 = nummern[(int) (Math.random() * 9 + 1)] + "";
teilnummern2 = nummern[(int) (Math.random() * 9 + 1)] + "";
teilnummern3 = nummern[(int) (Math.random() * 9 + 1)] + "";
teilnummern4 = nummern[(int) (Math.random() * 9 + 1)] + "";
return(teilnummern = teilnummern1 + teilnummern2 + teilnummern3 + teilnummern4 + "");
Then you should also do the same thing with the letters.
The indexes you are using for generating the plate are assigned once (The time you instace your class) so they are the same for all calls to plate-generating methods. Instead initializing those variables in the first place, try locating them within the methods generierekennzeichen() and generierenummern() as follows:
import java.util.*;
public class Kennzeichen {
char[] alphabet = new char[26];
char[] nummern = new char[10];
String teilstring;
String teilnummern1, teilnummern2, teilnummern3, teilnummern4, teilnummern;
String finale;
char a = 65; //ascii
char b = 48; // asci
int zahler = 0;
Scanner s = new Scanner(System.in);
int eineZahl = s.nextInt();
public void arrayalphabet() { // generates an array alphabet A-Z
for (int i = 0; i < alphabet.length; i++, a++) {
alphabet[i] = a;
}
}
public void arraynummern() { //generates numbers between 0 and 9
for (int i = 0; i < nummern.length; i++, b++) {
nummern[i] = b;
}
}
public String generierekennzeichen() { // first char must be B therefore alphabet[1]
int zahl = (int) ((Math.random()) * 25 + 1);
int zahl1 = (int) ((Math.random()) * 25 + 1);
return(teilstring = alphabet[1] + "" + alphabet[zahl] + "" + alphabet[zahl1]);
}
public String generierenummern() { // 4 numbers are generated and returned as total
int nummer1 = (int) (Math.random() * 9 + 1);
int nummer2 = (int) (Math.random() * 9 + 1);
int nummer3 = (int) (Math.random() * 9 + 1);
int nummer4 = (int) (Math.random() * 9 + 1);
teilnummern1 = nummern[nummer1] + "";
teilnummern2 = nummern[nummer2] + "";
teilnummern3 = nummern[nummer3] + "";
teilnummern4 = nummern[nummer4] + "";
return(teilnummern = teilnummern1 + teilnummern2 + teilnummern3 + teilnummern4 + "");
}
public void print() { //prints the total license such as B-AD 7645
System.out.println(finale = teilstring + "-" + teilnummern);
}
public void erzeugestack() { //using stack, not that important(just practise
Stack<String> s = new Stack<String>();
s.push(finale);
}
public void Abfrage() { // eineZahl is the input of the user, e.g 2
for(int i=0; i<eineZahl;i++){
generierekennzeichen();
generierenummern();
print();
}
}
public static void main(String[] args) {
Kennzeichen kennzeichen = new Kennzeichen();
kennzeichen.arrayalphabet();
// kennzeichen.generierekennzeichen();
kennzeichen.arraynummern();
// kennzeichen.generierenummern();
kennzeichen.Abfrage();
kennzeichen.erzeugestack();
}

Scrambling strings multiple times in eclipse

I'm having some trouble with some code for a program I'm writing. The purpose of this program is to take a word from a separate text file, scramble it ten times, and display the scrambled letters of the word. The problem that I'm having is that I'm unsure as to how I would go about scrambling the letters ten times. I know that the actual scrambling takes place in my mixer method but the how eludes me. I thought about using a for loop but I'm not sure how to go about it.
import java.io.*;
import java.util.*;
public class Scrambler {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("words.txt"));
String text = input.next();
System.out.println("Original Word: " + text);
System.out.println();
System.out.println("Scrambled Word:");
System.out.println("********");
separate(text);
System.out.println("********");
}
public static void separate(String text) {
System.out
.println(" " + text.charAt(0) + " " + text.charAt(1) + " ");
System.out.println(text.charAt(2) + " " + text.charAt(3));
System.out
.println(" " + text.charAt(4) + " " + text.charAt(5) + " ");
}
public static String mixer(String text) {
Random r = new Random();
int r1 = r.nextInt(text.length());
int r2 = r.nextInt(text.length());
String a = text.substring(0, r1);
char b = text.charAt(r1);
String c = text.substring(r1 + 1, r2);
char d = text.charAt(r2);
String e = text.substring(r2 + 1, text.length());
text = a + b + c + d + e;
return text;
}
}
Your mixer() is not working properly. I would first make the string into an char[], and then retrieve 2 random indices and switch the characters in these indices.
char[] stringasarray = text.toCharArray();
int length = text.length;
for(int i=0; i<length; i++){
int letter1 = rnd.nextInt(length);
int letter2 = rnd.nextInt(length);
char temp = stringasarray[letter1];
stringasarray[letter1] = stringasarray[letter2];
stringasarray[letter2] = temp;
}
String newtext = new String(stringasarray);
A simple for loop would do it:
String word = "Hello World";
for(int i = 0; i < 10; i++){
word = mixer(word);
}
Here is one approach for scrambling the string(s) ten times;
// Passing in the Random.
public static String mixer(String in, Random rnd) {
StringBuilder sb = new StringBuilder();
if (in != null) { // <-- check for null.
List<Character> chars = new ArrayList<Character>();
for (char ch : in.toCharArray()) {
chars.add(ch); // <-- add each character to the List.
}
Collections.shuffle(chars, rnd); // <-- "scramble"
for (char ch : chars) {
sb.append(ch);
}
}
return sb.toString();
}
public static void main(String[] args) {
String t = "Hello";
Random rnd = new Random();
// I'm not sure why you want to do it 10 times, but here is one way.
for (int i =0; i < 10; i++) {
t = mixer(t, rnd); // <-- call mixer function.
}
System.out.println(t);
}
public static String mixer(String text) {
Random r = new Random();
int r1 = r.nextInt(text.length()); // generates a random number from 0 to text.length - 1
int r2 = r.nextInt(text.length()); //generates a random number from 0 to text.length - 1
String a = text.substring(0, r1); // creates a substring containing characters from 0 to r1
char b = text.charAt(r1); //grabs the character at r1
String c = text.substring(r1 + 1, r2); // creates a substring from r1+1 to r2
char d = text.charAt(r2); // grabs the character at r2
String e = text.substring(r2 + 1, text.length()); // grabs any remaining characters
text = a + b + c + d + e; // recombines them
return text;
}
without delving into how substring works, this would most likely return the exact same string. If you changed the order of a + b + c + d + e it would scramble it. It takes the word and divides it into five pieces, then reassembles it.
It could probably use a lot of error checking, however, and some validation.

Testing for palindrome using loops going wrong

What this program is trying to do is go through numbers starting at "000000" going all the way up to "999999" and trying to find numbers which are palindromes. (eg: 0000000000).
I am having trouble with reversing the string and creating a valid result. The system adds the next 4 numbers creating a length 10 string.
import java.util.Arrays;
public class TestPalindrome{
public static void main(String []args){
int[] intArray = new int[6];
String[] strArray = new String[99];
String nextString;
int count = 0;
int nextnum;
int thisnum;
String thisString = "";
String s = "000000";
nextString = s;
do {
for(int i=0;i<6;i++) {
intArray[i] = Integer.parseInt(String.valueOf(nextString.charAt(i)));
}
int pos1 = intArray[5];
int pos2 = intArray[4]*10;
int pos3 = intArray[3]*100;
int pos4 = intArray[2]*1000;
int pos5 = intArray[1]*10000;
int pos6 = intArray[0]*100000;
nextnum = (pos1 + 1) + pos2 + pos3 + pos4 + pos5 + pos6;
thisnum = pos1 + pos2 + pos3 + pos4 + pos5 + pos6;
// If any of below values = 10, then number is not used
int d7 = ((4*intArray[0])+(10*intArray[1])+(9*intArray[2])+(2*intArray[3])+intArray[4]+(7*intArray[5])) % 11;
int d8 = ((7*intArray[0])+(8*intArray[1])+(7*intArray[2])+(intArray[3])+9*intArray[4]+(6*intArray[5])) % 11;
int d9 = ((9*intArray[0])+(intArray[1])+(7*intArray[2])+(8*intArray[3])+7*intArray[4]+(7*intArray[5])) % 11;
int d10 = ((intArray[0])+(2*intArray[1])+(9*intArray[2])+(10*intArray[3])+4*intArray[4]+(intArray[5])) % 11;
if (d7==10) { }
else if (d8==10) { }
else if (d9==10) { }
else if (d10==10) { }
else {
String s7 = Integer.toString(d7);
String s8 = Integer.toString(d8);
String s9 = Integer.toString(d9);
String s10 = Integer.toString(d10);
thisString = String.format("%06d", thisnum);
String concat = thisString + s7 + s8 + s9 + s10;
StringBuilder input = new StringBuilder(concat);
StringBuilder value = input.reverse();
if( value == input){
System.out.println("" + concat);
strArray[count] = concat;
count = count+1;
}
else {}
}
nextString = String.format("%06d", nextnum);
}
while (nextnum < 1000000 && nextnum > 000000);{
}
}
}
The problem is that it displays all numbers and not just palindromes. Any help is very welcomed.
I would simply put the numbers into strings. Then reverse the string and see if it equals the original.
String originalString = "110011";
String newString = new StringBuilder(originalString ).reverse().toString();
if (originalString.equals(newString )) {
//Is a palindrome
}
Note: Consider how you want to handle leading zeros. "11" is a palindrome, but if you need 4 values then "0011" is not.
One funny way is to use just one for-loop :
public static void main(String [] args){
for(String s = "000000"; !s.equals("1000000"); s = String.format("%06d",Integer.parseInt(s)+1)){
if(new StringBuilder(s).reverse().toString().equals(s))
System.out.println(s);
}
}

Categories

Resources