Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Колличество раундов проверки простоты числа
- let roundCount=1000;
- //factoryfunction, которая будет создавать объект с параметром "символ" и параметром "код"
- //тем самым давая возможность достаточно просто добавлять новые символы в алфавит сразу
- //вместе с их кодом
- const alphaFactory= (symbol,code) => {
- return {
- symbol,
- code
- }
- }
- //не самая удачная, но наиболее наглядная инициализация алфавита с использованием
- //описанной ранее функции
- let alpha=[];
- alpha.push(alphaFactory('а','10'));
- alpha.push(alphaFactory('б','11'));
- alpha.push(alphaFactory('в','12'));
- alpha.push(alphaFactory('г','13'));
- alpha.push(alphaFactory('д','14'));
- alpha.push(alphaFactory('е','15'));
- alpha.push(alphaFactory('ё','16'));
- alpha.push(alphaFactory('ж','17'));
- alpha.push(alphaFactory('з','18'));
- alpha.push(alphaFactory('и','19'));
- alpha.push(alphaFactory('й','20'));
- alpha.push(alphaFactory('к','21'));
- alpha.push(alphaFactory('л','22'));
- alpha.push(alphaFactory('м','23'));
- alpha.push(alphaFactory('н','24'));
- alpha.push(alphaFactory('о','25'));
- alpha.push(alphaFactory('п','26'));
- alpha.push(alphaFactory('р','27'));
- alpha.push(alphaFactory('с','28'));
- alpha.push(alphaFactory('т','29'));
- alpha.push(alphaFactory('у','30'));
- alpha.push(alphaFactory('ф','31'));
- alpha.push(alphaFactory('х','32'));
- alpha.push(alphaFactory('ц','33'));
- alpha.push(alphaFactory('ч','34'));
- alpha.push(alphaFactory('ш','35'));
- alpha.push(alphaFactory('щ','36'));
- alpha.push(alphaFactory('ъ','37'));
- alpha.push(alphaFactory('ы','38'));
- alpha.push(alphaFactory('ь','39'));
- alpha.push(alphaFactory('э','40'));
- alpha.push(alphaFactory('ю','41'));
- alpha.push(alphaFactory('я','42'));
- alpha.push(alphaFactory('0','43'));
- alpha.push(alphaFactory('1','44'));
- alpha.push(alphaFactory('2','45'));
- alpha.push(alphaFactory('3','46'));
- alpha.push(alphaFactory('4','47'));
- alpha.push(alphaFactory('5','48'));
- alpha.push(alphaFactory('6','49'));
- alpha.push(alphaFactory('7','50'));
- alpha.push(alphaFactory('8','51'));
- alpha.push(alphaFactory('9','52'));
- //Необходимые функции
- //Данная функция по введенному p вернет оптимальное кол-во символов в одном блоке
- //что необходимо для оптимизации работы программы и корректной ее работы
- const blocksLength = number => {
- let count=1;
- number=Math.trunc(number/10);
- while (number>0) {
- count++;
- number=Math.trunc(number/10);
- }
- return count-1;
- }
- console.log(blocksLength(95617));
- //функция представления числа x как 2^buf*t, необходима для теста Миллера-Рабина
- const breakeNumber = number => {
- let buf=0;
- while (number%2===0) {
- buf++;
- number=number/2;
- }
- return [buf,number]; //buf - степень двойки s, t; number - t
- }
- const genRand = (min,max) => {
- return Math.floor(Math.random()*(max-min)+min);
- }
- //Функция для возведения в степень по модулю
- const powMod = (number,pow, mod) => {
- let c=1;
- for (let i=1;i<=pow;++i) {
- c=(c*number)%mod;
- }
- return c;
- }
- //тест Миллера-Рабина
- const checkSimple = (n,roundCount) => {
- if (n===2||n===3) {
- return true;
- }
- if (n<2||n%2==0) {
- return false;
- }
- let s=breakeNumber(n-1)[0];
- let t=breakeNumber(n-1)[1];
- for (let i=0;i<roundCount;++i) {
- let a=genRand(2,n-2);
- let x=powMod(a,t,n);
- if (x===1||x===n-1) {
- continue;
- }
- for (let r=0;r<s;r++) {
- x=(x*x)%n;
- if (x==n-1) break;
- }
- if (x!=n-1) return false;
- }
- return true;
- }
- //Функция, которая будет возвращать первообразный корень, либо -1 в случае его отсутствия
- const findSqrt=p => {
- let fact =[];
- let phi=p-1;
- let n=phi;
- for (let i=2;(i*i)<=n;++i) {
- if (n%i==0) {
- fact.unshift (i);
- while (n%i==0) {
- n=n/i;
- }
- }
- }
- if (n>1) {
- fact.unshift(n);
- }
- for (let res=2;res<=p;res++) {
- let ok=true;
- for (let i=0;(i<fact.length&&ok);i++) {
- if (powMod(res,phi/fact[i],p)!=1) {
- ok=true;
- } else {
- ok=false;
- }
- }
- if (ok) return res;
- }
- return -1;
- }
- //функция берет на вход строку, проходится по каждому символу и выводит
- //представление только указанных в заднии символов входой строки в
- //цифровую форму
- const codeMessage = (message) => {
- let outputString=[];
- for (let i=0;i<message.length;++i) {
- let buf=message[i];
- console.log(buf);
- for (let j=0;j<alpha.length;++j) {
- if (alpha[j].symbol===buf) {
- outputString+=alpha[j].code;
- }
- }
- }
- return outputString;
- }
- //НОД
- const gcd=(a,b) => {
- if (b==0) return a;
- return gcd(b,a%b);
- }
- const getK = (P) => {
- let buf=Math.floor(Math.random()*P);
- while (gcd(P,buf)!=1) {
- buf=Math.floor(Math.random()*P);
- }
- return buf;
- }
- const makeBlock = (r,e) => {
- return r+","+e+" ";
- }
- //Следующие 2 функции будут искать кол-во цифер в числах r и e, чтобы корректно
- //извлечь их из криптограммы
- const findR = string => {
- let temp=",";
- let count=0;
- while (string[count]!=temp) {
- count++;
- }
- return count;
- }
- const findE = string => {
- let temp=" ";
- let count=0;
- while (string[count]!=temp) {
- count++;
- }
- return count;
- }
- //Основная часть
- //Сообщение инициализируется тут
- let message="2 2 а б р к а д а б р а";
- let m=15;
- //вводим p
- let p=96157;
- if (!checkSimple(p)) {
- console.log(`Ошибка: введенное p является составным`)
- } else {
- //Перевод символов открытого текста в цифровую форму
- let messageCoded=codeMessage(message);
- console.log(messageCoded);
- //для данного P находим первобразный корень
- let g;
- g=findSqrt(p);
- console.log(`g=${g} p=${p}`);
- //Создаем двух пользователей, если режим шифрования, и вводим секретные ключи пользователей
- //если режим дешифрования
- //Первый пользователь
- let c1=genRand(2,p-3);
- let d1=powMod(g,c1,p);
- //Второй пользователь
- let c2=genRand(2,p-3);
- let d2=powMod(g,c2,p);
- //шифрование
- let cryptogramm="";
- while (messageCoded.length>0) {
- let temp=messageCoded.slice(0,blocksLength(p));
- messageCoded=messageCoded.substring(blocksLength(p));
- console.log(`До кодировки=${temp}`);
- console.log(messageCoded);
- let k=getK(p-3);
- let r=powMod(g,k,p);
- let e=(temp*powMod(d2,k,p))%p;
- console.log(`r=${r} e=${e}`);
- cryptogramm=cryptogramm+makeBlock(r,e);
- //cryptogramm+=',';
- ///cryptogramm+=e;
- //cryptorramm+=' ';
- }
- console.log(cryptogramm);
- //Дешифровани
- let openTextDigital="";
- while (cryptogramm.length>3) {
- let r=cryptogramm.substring(0,findR(cryptogramm));
- cryptogramm=cryptogramm.substring(findR(cryptogramm)+1);
- let e=cryptogramm.substring(0,findE(cryptogramm));
- cryptogramm=cryptogramm.substring(findE(cryptogramm)+1);
- let m=(e*powMod(r,p-1-c2,p))%p;
- console.log(`r=${r} e=${e} m=${m}`);
- openTextDigital+=m;
- }
- console.log(openTextDigital);
- let openText="";
- while (openTextDigital.length>0) {
- let temp=openTextDigital.substring(0,2);
- openTextDigital=openTextDigital.substring(2);
- for (let i=0;i<alpha.length;++i) {
- if (alpha[i].code==temp) {
- openText=openText+alpha[i].symbol;
- }
- }
- }
- console.log(openText);
- }
Add Comment
Please, Sign In to add comment