Javascript-форум (https://javascript.ru/forum/)
-   Серверные языки и технологии (https://javascript.ru/forum/server/)
-   -   Как работает Punycode? Алгоритм!!! (https://javascript.ru/forum/server/34225-kak-rabotaet-punycode-algoritm.html)

platedz 25.12.2012 00:55

Как работает Punycode? Алгоритм!!!
 
Уже не знаю, где спросить, поэтому попробую здесь, может кто ответит
Купил скрипт конструктор сайтов, но он не поддерживает русские домены.
Спецификацию RFC 3492 я почитал, хотя с ангийским довольно недружен, но тем не менее. Класс для создания Idn доменов я нашел, но как работает так и не понял. Объясните пожалуйста.

platedz 25.12.2012 17:46

Вот нашел класс на javascript
https://github.com/bestiejs/punycode...er/punycode.js
Может кто поможет разобраться как он работает

platedz 26.12.2012 07:36

Разбирая класс http://phlymail.com/en/downloads/idna-convert.html в целом я застрял на конечном автомате, с которым познакомился только сегодня. Т.е. смысл кодировки сводится к тому, чтобы привести символы в их десятиричное представление. Убрать все не ascii символы, спереди добавить xn-- а в конце -. А дальше уже идет алгоритм конечного автомата, который кроется в функции protected function _encode($decoded) и мне не очень понятен.
Соответственно вопрос в том как работает конечный автомат, соответственно, для данного случае интересует больше. Но любой ответ будет в помощь

platedz 02.01.2013 00:44

С алгоритмом частично разобрался. Подскажите, пожалуйста, а как мне в виде двоичного числа символ отобразить в виде 0101010101 или 0x02?

melky 02.01.2013 01:00

var letter = "s"; // строка с длиной  в 1 символ
var base = 2; // в какую систему

var encoded = letter.charCodeAt().toString(base);

alert(encoded);

platedz 02.01.2013 01:15

Большое спасибо за ответ. Только что-то я не нашел, где описаны данные свойства объекта.

platedz 02.01.2013 01:22

Все понял.

platedz 02.01.2013 01:22

http://javascript.ru/Number/toString

platedz 02.01.2013 16:21

Подскажите, а как-нибудь нулями отсутствующими его заполнить можно для наглядности, а то получается то 101, то 11001, а надо чтобы было 00000101 и 00011001

platedz 02.01.2013 17:29

И подскажите, пожалуйста почему
Ни так не получается
<script>
var R = ("9");
var RR = ~R;
var Rs = R + " - " + R.charCodeAt().toString(10) + " - " + R.charCodeAt().toString(2) + " - " + R.charCodeAt().toString(16) + "<br>";
Rs += "~ - " + (RR.charCodeAt().toString(10)) + " - " + (RR.charCodeAt().toString(2)) + " - " + (RR.charCodeAt().toString(16)) + "<br>";
document.write(Rs);
</script>


ни так не получается

<script>
var R = ("9");
var Rs = R + " - " + R.charCodeAt().toString(10) + " - " + R.charCodeAt().toString(2) + " - " + R.charCodeAt().toString(16) + "<br>";
Rs += "~ - " + ~(R.charCodeAt().toString(10)) + " - " + ~(R.charCodeAt().toString(2)) + " - " + ~(R.charCodeAt().toString(16)) + "<br>";
document.write(Rs);
</script>

melky 02.01.2013 17:45

// символы в строке заменятся другими, справа налево
var buffer = "00000000000000";
var base = 2; // в какую систему


// строка для примера. покажем для неё коды символов
var letters = "Учи JS"; 
var i = 0;

while (i < letters.length) {

    var letter = letters.charAt(i++); // строка с длиной  в 1 символ

    var encoded = letter.charCodeAt().toString(base);

    var replaced = buffer.slice(0, buffer.length - encoded.length).concat(encoded);

    alert('Символ "' + letter + '"\nВ двоичной системе: "' + replaced + '"');

}

platedz 02.01.2013 17:47

Да и вообще не ясно как вообще применить и главное посмотреть результат при применении.
~
>>
<<
>>>
Скажем взял я какой-нибудь символ и хочу посмотреть как он выглядит в двоичной системе в 16-ричной и 10-ричной.
А потом тоже самое хочу посмотреть со сдвигом, и с отрицанием и тд.

Deff 02.01.2013 17:57

var a = '101';
var b = '11101';

function replac(a){
var z = '00000000';
var Len=a.split("").length;
a=z.substring(0,8-Len)+a;
return a;
}

a=replac(a)
alert(a)
b=replac(b)
alert(b)

platedz 02.01.2013 18:14

Спасибо за ответ, просто я думал, может там как-то настроить можно это дело, а не вручную выправлять.
Если не сложно то, ответьте пожалуйста, как же мне со смещениями и тд. вывести результат

Deff 02.01.2013 19:11

Цитата:

Сообщение от platedz
Если не сложно то, ответьте пожалуйста, как же мне со смещениями и тд. вывести результат

http://javascript.ru/bitwise-operators

platedz 02.01.2013 20:07

Я как раз вот это читаю
http://learn.javascript.ru/bitwise-operators

Пытаюсь вывести к примеру

var R = ("9");
var Rs = R + " - " + R.charCodeAt().toString(10) + " - " + R.charCodeAt().toString(2) + " - " + R.charCodeAt().toString(16) + "<br>";
Rs += "~ - " + ~(R.charCodeAt().toString(10)) + " - " + ~(R.charCodeAt().toString(2)) + " - " + ~(R.charCodeAt().toString(16)) + "<br>";
document.write(Rs);


А получаю
9 - 57 - 111001 - 39
~ - -58 - -111002 - -40

т.е. как минимум 111002 это явно не то, что я хотел увидеть

platedz 02.01.2013 20:11

Т.е. я так понимаю, или & и | вывести нельзя, а остальные насколько я понял имеют отпределенное значение, только не понял, как их вывести таким способом.

Deff 02.01.2013 20:14

platedz,
Я не вник задачу - что у Вас на входе - приведите массив
И что должно получицо на выходе - приведите массив

platedz 02.01.2013 20:58

на входе у меня символ, я хочу получить ее в виде десятичного числа, двоичного и шестнадцатиричного, возьму только двоичный пока т.к. сразу видно из него, что получаю не то
var R = ("9");
alert(R.charCodeAt().toString(2));

Получил 111001
А теперь пытаюсь получить все тот же символ, но с побитовым не ~R

Но вместо 000110, как ожидаю получаю 111002.

platedz 02.01.2013 21:32

http://learn.javascript.ru/bitwise-o...овое-не

Так вот мне нужно в двоичном представлении именно из переменной R1, но, т.е. что-то навроде
R2 = ~R1;
И оба варианта получить в двоичной форме.
Т.е. я так понимаю если
var R1 = ("9"); в двоичной форме 111001;
то
var R2 = ~R1; в двоичной форме мне должно дать 000110;
но как не пробовал получить не могу.
Т.е. в обоих вариантах на входе переменная R1 c символом
А на выходе нужен тот же символ в двоичной форме и в двоичной форме с ~

Примерно как описано по ссылке

9 (по осн. 10)

= 00000000000000000000000000001001 (по осн. 2)

~9 (по осн. 10)

= 11111111111111111111111111110110 (по осн. 2)

Deff 02.01.2013 21:56

function replac(a){
var z = '00000000';
var Len=a.split("").length;
a=z.substring(0,8-Len)+a;
return a;
}
//=============

var R = ("9");

var R1=R.charCodeAt();
var R2=255-R1;
alert(replac(R1.toString(2))+'\n'+R2.toString(2));

platedz 02.01.2013 22:05

А еще непонятно почему

alert(0050);

выводит мне 40

platedz 02.01.2013 22:08

Спасибо, только вот оператора
~
нету в Вашем коде. Я как бы спрашивал, для того, чтобы получить именно результат его работа, и увидеть наглядно, а также других побитовых операторов.

Deff 02.01.2013 22:08

platedz,
Ощущение что дурь всё это - на PHP трансформация UTF в кирилицу одной строкой

Deff 02.01.2013 22:12

Перекодировка скриптом:
http://stackoverflow.com/questions/2...avascript?rq=1

platedz 02.01.2013 22:41

Про дурь, и то что Вы хотели показать, мне по ссылке я не очень понял.
А как-то вывести результат из двоичной системы можно. Т.е. чтобы на входя был 01010101 а на выходе уже символ

Deff 02.01.2013 22:44

platedz,
По ссылке преобразование из UTF в windows-1251
про дурь же:
На PHP это преобразование можно выполнить одной строкой

Или я не вкурил проблему ?

melky 02.01.2013 22:57

Цитата:

Сообщение от platedz
А как-то вывести результат из двоичной системы можно. Т.е. чтобы на входя был 01010101 а на выходе уже символ

String.fromCharCode

platedz 02.01.2013 22:58

Нет я не преобразовываю из одной кодировки в другую, я просто, так сказать изучаю работу побитовых операторов и хочу увидеть визуально, вывести результат.

platedz 02.01.2013 23:46

Так я и не понял, как мне с помощью fromCharCode вывести символ передав его в двоичном виде, и в шестрадцатеричном тоже. В десятичном понятно, все работает нормально.
И почему 0050 это ), т.е. я так понял что 0050 возвращает 40, тк. 40 это кавычка в utf-8, а что это за 0050, в какой кодировке

Deff 02.01.2013 23:53

function replac(a){
var z = '00000000';
var Len=a.split("").length;
a=z.substring(0,8-Len)+a;
return a;
}
//=============

var R = ("9");

var R1=R.charCodeAt();
var R2=255-R1;
alert(replac(R1.toString(2))+'\n'+replac(R2.toString(2))+'\n\n'+R1.toString(16)+'\n'+R2.toString(16));

platedz 03.01.2013 01:34

Ваш пример довольно наглядный, но к сожалению в нем не выполняется бинарный оператор, что для меня более важно.
И я не понял для чего это


var R = ("9");
var R1=R.charCodeAt();
var R2=255-R1;
alert(replac(R1.toString(2))+'\n'+replac(R2.toString(2))+'\n\n'+R1.toString(16)+'\n'+R2.toString(16));




Я сделал так

<style>
.a01 td {border-left: 1px solid black; text-align: right;}
.a01 tr {border-top: 1px solid black;}
</style>
<script>


Punycode = function() 
	{ 
	
	Er = false;
	function nul32 (m,n) 
		{ 
		
		var nu =  "";
		for(var i=0; i<n; i++) nu += "0";
		return ((m.indexOf("-") != -1)? "-":"")+(nu.slice(0,((m.indexOf("-") != -1)?n+1:n)-m.length).concat((m.indexOf("-") != -1)?m.substring(1):m));
		
		}
	function litBig(R,s)
		{
			var R1 = R.charCodeAt();
			var R2 = (R1 << 1);
			var R3 = (R1 >> 1);
			var R4 = ~(R1);
			
			var Rs = "<tr style='border-top: 1px solid black;'><td>" + R + "</td><td>" + nul32(R1.toString(10),4)  + "</td><td>" +  nul32(R1.toString(2),32)  + "</td><td>" +  nul32(R1.toString(16),4) +  "</td><td>" + String.fromCharCode(R1.toString(10)) + "</td></tr>";
												Rs += "<tr><td>" + "~" + "</td><td>" + nul32(R4.toString(10),4)  + "</td><td>" +  nul32(R4.toString(2),32)  + "</td><td>" +  nul32(R4.toString(16),4) +  "</td><td>" + String.fromCharCode(R4.toString(10)) + "</td></tr>";
												Rs += "<tr><td>" + "<< 1" + "</td><td>" + nul32(R2.toString(10),4)  + "</td><td>" +  nul32(R2.toString(2),32)  + "</td><td>" +  nul32(R2.toString(16),4) +  "</td><td>" + String.fromCharCode(R2.toString(10)) + "</td></tr>";
												Rs += "<tr><td>" + ">> 1" + "</td><td>" + nul32(R3.toString(10),4)  + "</td><td>" +  nul32(R3.toString(2),32)  + "</td><td>" +  nul32(R3.toString(16),4) +  "</td><td>" + String.fromCharCode(R3.toString(10)) + "</td></tr>";

		return Rs;	
		}
	
	return {

		
			inp: function (d) 
				{ 
					var m = "<table class='a01'>";
					for(var i=0; i<d.length; i++)
						{
						
							m += litBig(d[i]) + "";
						
						
						}
					 m += "</table>";
						
					if(Er) { document.getElementById("PunycodeError").innerHtml = ""; }
					document.getElementById("Punycode").innerHTML = m;			
				},
		
		
		}

	}();
	
</script>	
<div id="PunycodeError"></div>
<input onKeyUp="Punycode.inp(this.value);">
<div id="Punycode"></div>


Единственное, что мне не очень понятно, почему при " ~ " возвращает на 1 больше? Т.е. если R1 возвращает 0057, то R4 -0058

Deff 03.01.2013 01:40

platedz,
" ~ " работает с 32 разрядными числами, а Вам нужно байтовое представление
поэтому тупо
var R2=255-R.charCodeAt();
чтобы преобразовать в двоичный или 16
R2.toString(2);
R2.toString(16);
для дополнения нулями в двоичном представлении - итог в двоичном суём в функцию => replac(a)

platedz 03.01.2013 01:50

Так а это что?
var R2=255-R1
А самое главное что за c6, которое оно выдает?

Deff 03.01.2013 01:59

Цитата:

Сообщение от platedz
Так а это что?

Это аналог "~" для байтового представления
255 в двоичном - это все единички - из всех единичек вычитаем установленные
11111111
-
00111001
__________
11000110

Цитата:

Сообщение от platedz
А самое главное что за c6, которое оно выдает?

11000110 двоичное = это шестнадцетиричное С6 = десятичное 198

platedz 03.01.2013 02:21

Так насколько я понимаю, при ~ идет отрицание при 32 битном представлении.
Т.е.

9 = 00000000000000000000000000001001
~9 = 11111111111111111111111111110110

а в Вашем случае видимо получается

9 = 00000000000000000000000000111001
~9 = 00000000000000000000000011000110

При этом любой символ с ~ в принципе не существует, т.к. отрицательных кодов символов нет.

platedz 03.01.2013 02:46

Большое спасибо за ответ, в общем и целом для меня осталось неясно
Почему alert(0050) выводит мне 40 и что это за 0050?
Почему при " ~ " возвращает на 1 больше? Т.е. если R1 возвращает 0057, то R4 -0058

Deff 03.01.2013 03:07

Числа начинаюшиеся с нулей - по умолчанию считаются восьмеричными и
alert все трансформирует на выходе в десятичный код
alert(0050)
alert(parseInt(0050,10));
alert(0100);

Deff 03.01.2013 03:12

Если входная строка начинается с "0х", то radix = 16
Если входная строка начинается с "0", то radix = 8. Этот пункт зависит от реализации и в некоторых браузерах (Google Chrome) отсутствует.
В любом другом случае radix=10

alert(50)
alert(050);
alert(0x050);
alert(0100);

platedz 03.01.2013 05:53

Спасибо, вроде во всем разобрался, с ~ осталось как-то неясно


Часовой пояс GMT +3, время: 07:45.