Мой алгоритм шифрования

от автора

Не так давно передо мною встала задача закодировать переписку пользователей. Целью задачи было пересылать уже закодированную строку от пользователя А пользователю Б. Строка кодируется и декодируется с помощью ключа, который известен обоим. Подразумевается, что сообщение от пользователя А отсылается на сервер пользователю Б, где пользователь Б его и забирает. Чтобы избежать получение данных в случае получения сообщения третьим лицом путем перехвата сообщения, либо доступа к серверу, где оно хранится, функцию было решено организовать на JavaScript, что дает возможность пользователям отсылать закодированную строку прямо из окна браузера.

Бегло пробежавшись по некоторым способом шифрования, я решил написать собственный алгоритм. Суть алгоритма было решено свести к тому, чтобы перемешивать каждый отдельный символ в неким уникальным значением смешанным с ключом, причем так, чтобы значение, которое будет смешивать данные символы было уникальным и формировалось из заданного пароля или ключа. Творческой идеей для написания именно такого алгоритма послужил шифр Эль-Гамаля, метод преобразования Punycode и Base64. На нобелевскую премию я не претендую, но тем не менее решил поделиться собственным творением и…

passCode — пароль, ключ. Так как пользователь задает данный параметр самостоятельно, а он может быть достаточно простым, то я кодирую ее дополнительно в MD5.
Incode — кодируемая строка

function txtencode(Incode, passCode) { 	//Так как сам результат может содержать нежелательные символы, эта переменная содержит символы с помощью которых мы будем выдавать закодированный результат, который вдальнейшем сможем отправить без особых хлопот 	var b52 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 	//Эти переменные будут меняться в процессе кодировки и создавать мешанину каждого кодируемого символа в отдельности 	var maxPC = ifPC = 0; 	//Уникализируем переменную maxPC. Ее значение будет происходить от суммы каждого юникодного значения символов пароля 	for(var i=0; i<passCode.length; i++) maxPC += passCode.charCodeAt(i); 	//Значение maxPCmod будет меняться на убывание, опять же в зависимости от юникодного значения символа пароля 	//А вот значение maxPC сохраним, оно понадобиться вдальнейшем, чтобы присвоить переменной maxPCmod новое значение, когда то будет меньше 0. 	maxPCmod = maxPC; 	//Результат кодируемой строки. Изначально равно пустоте.  	var rexcode = ""; 	//Переменная содержит первый символ пароля: passCode.charCodeAt(numPC) 	//С ее помощью будем перебирать пароль и перемешивать его с символом строки 	var numPC = 0; 	//Перебираем каждый символ строки 	for(var i=0; i<Incode.length; i++)  	{ 		//Если все символы пароля перемешаны, начинаем перебор пароля с первого символа 		if(numPC == passCode.length) numPC = 0; 		//Присвоиваем переменной maxPCmod новое значение, если оно меньше нуля. 		if(maxPCmod < 1) maxPCmod = maxPC+ifPC; 		//Эта переменная нужна для создания уникального значения maxPCmod, и как следствие уникального символа, с которым будет перемешиваться символ исходной строки. 		// Получаем ее путем деления по модулю значений maxPCmod и текущего используемого юникодного значения символа пароля  		//В целом постоянная мешанина переменных maxPCmod, maxPC и ifPC позволяет кодировать каждый отдельный символ исходной строки с уникальным значением, что подразумевает невозможность отследить какую-либо синхронизацию алгоритма 		ifPC += maxPCmod % passCode.charCodeAt(numPC); 		//Создаем непосредственно символ, с которым и будем перемешивать текущий символ строки 		var iscode = maxPCmod % passCode.charCodeAt(numPC); 		//Создаем мешанину, путем сложения предыдущей переменной с переменной текущего символа 		var nCode = (Incode.charCodeAt(i)+iscode); 		//Уменьшаем значение maxPCmod для ее дальнейшей уникализации 		maxPCmod -= passCode.charCodeAt(numPC); 		//Переходим к следующему символу пароля 		numPC++; 		//Это будет уникальный номер текущего символа. 		//При делении закодированного символа на 52 число означает неполное частно, а буква остаток.  		//Например 22С означает 22*52+2, так как С второй по счету символ начиная с нуля. 		rexcode += parseInt(nCode / 52) + b52.charAt(parseInt(nCode % 52)); 	} 	//Возвращаем закодированную строку 	return rexcode; } 

Функция декодировки практически аналогично предыдущей за небольшими исключениями

function txtdecode(Incode, passCode) { 	var b52 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 	var maxPC = 0; 	for(var i=0; i<passCode.length; i++) maxPC += passCode.charCodeAt(i); 	maxPCmod = maxPC; 	ifPC = 0; 	//Разбиваем строку на массив, который будет состоять из каждого закодированного символа 	var Incode = Incode.match(/\d+\w/g); 	var rexcode = ""; 	var numPC = 0; 	for(var i=0; i<Incode.length; i++)  	{ 		if(numPC == passCode.length) numPC = 0; 		if(maxPCmod < 1) maxPCmod = maxPC+ifPC; 		ifPC += maxPCmod % passCode.charCodeAt(numPC); 		var iscode = maxPCmod % passCode.charCodeAt(numPC); 		//В отличии от фунции кодирования, тут дейтсвие происходит в обратную сторону 		var nCode = (parseInt(Incode[i])*52)+parseInt(b52.indexOf(Incode[i].substr(-1))); 		maxPCmod -= passCode.charCodeAt(numPC); 		numPC++; 		//И в результате соответственно уже не сложение, а вычитание 		rexcode += String.fromCharCode(nCode-iscode); 	} 	//Уже можно вернуть return rexcode. 	//Но для корректного отображения в браузере, я преобразую некоторые символы во мнемоники, а урлы преобразую в ссылки. 	return rexcode.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/ /g, " ").replace(/\r\n|\r|\n/g,"<br />").replace(/(https?\:\/\/|www\.)([а-яА-Я\d\w#!:.?+=&%@!\-\/]+)/gi, function(url)  	{ 		return '<a target="_blank" href="'+ (( url.match('^https?:\/\/') )?url:'http://' + url) +'">'+ url +'</a>'; 	});  } 

ссылка на оригинал статьи http://habrahabr.ru/post/262081/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *