Skip to content

Instantly share code, notes, and snippets.

@antoniojxk
Forked from davidhmaciasv/Criptografia.java
Created May 10, 2017 17:37
Show Gist options
  • Save antoniojxk/a073d894b62ea8b99ca13c407ebfd56c to your computer and use it in GitHub Desktop.
Save antoniojxk/a073d894b62ea8b99ca13c407ebfd56c to your computer and use it in GitHub Desktop.
recibe una llave publica y genera la llave privada
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class Criptografia {
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(System.out);
BufferedReader tec = new BufferedReader(new InputStreamReader(System.in));
System.out.println("llave publica separada por espacio de forma (e n)");
StringTokenizer st = new StringTokenizer(tec.readLine());
System.out.println("texto");
String line = tec.readLine().toLowerCase();
int e = Integer.parseInt(st.nextToken());
int n = Integer.parseInt(st.nextToken());
int[] arr = factorizaciones(n);
int p = arr[0];
int q = arr[1];
int fi = (p - 1) * (q - 1);
int d = (int) gcdExtendido(e, fi)[1];
out.println("la llave privada es " + d + " " + n);
out.print("el resultado es: ");
int seg = 3;
int pots = 27;
// for (seg = 0; pots < n; seg++)
// pots*=27;
System.out.println("numero de segmentacion");
seg = Integer.parseInt(tec.readLine().trim());
System.out.println("c para cifrado d para desifrado");
char cifrando = tec.readLine().trim().charAt(0);
long suma = 0;
for (int i = 0; i < line.length(); i++) {
int pot = seg - 1 - (i % seg);
suma += valorDeCaracter(line.charAt(i)) * Math.pow(27, pot);
if ((i + 1) % seg == 0) {
// para cifrar con e, para decifrar con d
String bin = "";
if (cifrando == 'c')
bin = Long.toBinaryString(e);
else if (cifrando == 'd')
bin = Long.toBinaryString(d);
long res = 1;
long m = suma;
for (int j = bin.length() - 1; j >= 0; j--) {
if (bin.charAt(j) == '1')
res = (res * m) % n;
m = (m * m) % n;
}
m = res;
StringBuffer sb = new StringBuffer();
pots = 27;
while (pots < m) {
sb.append(valorDeCaracter((int) m % pots));
m -= m % pots;
pots *= 27;
}
pots /= 27;
sb.append(valorDeCaracter((int) m / pots));
out.print(sb.reverse());
suma = 0;
}
}
out.println();
out.close();
}
static int valorDeCaracter(char c) {
if (c <= 'n')
return c - 'a';
if (c == 'ñ')
return 'n' + 1 - 'a';
return c + 1 - 'a';
}
static char valorDeCaracter(int c) {
c += 'a';
if (c <= 'n')
return (char) c;
if (c == 'o')
return 'ñ';
return (char) (c - 1);
}
static int[] factorizaciones(int n) {
int[] primos = primos(1000);
for (int i = 0; i < primos.length; i++) {
if (n % primos[i] == 0)
return new int[] { primos[i], n / primos[i] };
}
return null;
}
static int[] primos(int M) {
boolean b[] = new boolean[M];
int i, j, k, c = 2;
for (i = 2; (k = i * i) < M; i++)
if (!b[i])
for (j = k; j < M; j += i)
if (!b[j]) {
b[j] = true;
c++;
}
int r[] = new int[M - c];
for (i = 2, j = 0; i < M; i++)
if (!b[i])
r[j++] = i;
return r;
}
static long[] gcdExtendido(long a, long b) {
// answer[0]=gcd(a,b),
// answer[1]*a+answer[2]*b=gcd(a,b)
boolean bs = a < b;
long xAnt = 1, yAnt = 0, x = 0, y = 1;
if (bs) {
long tmp = a;
a = b;
b = tmp;
}
while (b != 0) {
long q = a / b, r = a % b, xTmp = xAnt - q * x, yTmp = yAnt - q * y;
a = b;
b = r;
xAnt = x;
yAnt = y;
x = xTmp;
y = yTmp;
}
return new long[] { a, bs ? yAnt : xAnt, bs ? xAnt : yAnt };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment