Как стать автором
Обновить

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

Время на прочтение4 мин
Количество просмотров21K
Не так давно передо мною встала задача закодировать переписку пользователей. Целью задачи было пересылать уже закодированную строку от пользователя А пользователю Б. Строка кодируется и декодируется с помощью ключа, который известен обоим. Подразумевается, что сообщение от пользователя А отсылается на сервер пользователю Б, где пользователь Б его и забирает. Чтобы избежать получение данных в случае получения сообщения третьим лицом путем перехвата сообщения, либо доступа к серверу, где оно хранится, функцию было решено организовать на 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>';
	}); 
}


Результат можно увидеть на сайтах avtodot.ru, baby-all-pro.ru и building-repairs.ru

Юридические аспекты шифрования данных
Теги:
Хабы:
Всего голосов 65: ↑7 и ↓58-51
Комментарии29

Публикации

Истории

Работа

Ближайшие события