Кіріспе
Юникод домендік атауларын кодтау
Punycode – интернет хост атаулары үшін қолданылатын шектеулі ASCII таңбалар жиынтығы арқылы Юникодты бейнелеу тәсілі. Punycode-ты пайдалану арқылы Юникод таңбаларын қамтитын хост атаулары, әріптерден, цифрлардан және дефистен тұратын ASCII-нің ішкі жиымына транскодталады, бұл әріп-цифр-дефис (LDH) жиыны деп аталады. Мысалы, Мюнхен (Мюнхен қаласының немісше атауы) Mnchen 3ya деп кодталады. Домендік атаулар жүйесі (DNS) домендік атау белгілерінде кез келген октеттер тізбегін техникалық тұрғыдан қолдайды, бірақ DNS стандарттары хост атаулары үшін дәстүрлі түрде қолданылатын ASCII LDH жиынын пайдалануды ұсынады және DNS домендік атауларын салыстыру кезінде жазу тіліне қарамастан салыстыру қажеттігін талап етеді. Punycode синтаксисі – интернационалданған домендік атаулар (IDNA) сияқты Юникод таңбаларын қамтитын тізбектерді DNS-тің бағалайтын ASCII LDH жиымына кодтау әдісі. Ол IETF сұранысы 3492-де сипатталған.
Punycode is a representation of Unicode with the limited ASCII character subset used for Internet hostnames. Using Punycode, host names containing Unicode characters are transcoded to a subset of ASCII consisting of letters, digits, and hyphens, which is called the letter–digit–hyphen (LDH) subset. For example, München (German name for Munich) is encoded as Mnchen 3ya. While the Domain Name System (DNS) technically supports arbitrary sequences of octets in domain name labels, the DNS standards recommend the use of the LDH subset of ASCII conventionally used for host names, and require that string comparisons between DNS domain names should be case insensitive. The Punycode syntax is a method of encoding strings containing Unicode characters, such as internationalized domain names (IDNA), into the LDH subset of ASCII favored by DNS. It is specified in IETF Request for Comments 3492.
Сипаттама
RFC 3492-де айтылғандай, "Punycode – Bootstring деп аталатын жалпы алгоритмнің бір түрі, ол "негізгі" кодтық таңбалардың шағын жиынтығынан құралған тізбектерді үлкен жиынтықтан алынған кез келген кодтық таңбалар тізбесін бірегей түрде көрсетуге мүмкіндік береді". Punycode жалпы Bootstring алгоритміне Юникод мәтінінің ерекшеліктеріне сәйкес келетін параметрлерді анықтайды. Бұл бөлім "bücher" (Bücher – неміс тілінде кітаптар) тізбегін "bcher kva" белгісіне түрлендіру арқылы Punycode кодтау процедурасын көрсетеді. Кодтау және декодтау алгоритмдерін оңайлату үшін кейбір кодталған мәндердің рұқсат етілмейтін Юникод мәндерін кодтауына жол бермеу үшін ешқандай әрекет жасалмады: алайда, оларды декодтау кезінде тексеру және анықтау қажет. Punycode барлық жазу жүйелерінде жұмыс істеуге және жұмыс істегенде таңбалар жиынтығының диапазонына бейімделуге тырысу арқылы өзін-өзі оңтайландыруға арналған. Бұл тізбек нөл немесе одан көп ASCII таңбаларынан және сондай-ақ тек бір басқа жазу жүйесінің таңбаларынан тұратын жағдайда оңтайландырылған, бірақ кез келген кездейсоқ Юникод тізбегімен жұмыс істейді. DNS пайдалану үшін домендік атау тізбегі Punycode-қа енгізілгенге дейін nameprep арқылы қалыпқа келтірілді деп есептеледі және (жоғары деңгейлі домендер үшін) ресми тіркелген тіл кестесіне сәйкес сүзгіленеді, ал DNS протоколы Punycode шығыс тізбегінің рұқсат етілген ұзындығына шектеу қояды.
ASCII таңбаларының бөлінуі
Біріншіден, жолдағы барлық ASCII таңбалары кірістен шығысқа көшіріледі, басқа таңбаларды жіберіп алады. Мысалы, "bücher" сөзі "bcher" деп көшіріледі. Егер қандай да бір таңбалар көшірілсе, яғни кірісте кем дегенде бір ASCII таңбасы болса, шығысқа ASCII дефисі қосылады (мысалы, "bücher" → "bcher-", бірақ "ü" → ""). Дефистердің өзі ASCII таңбалары екенін ескеріңіз. Осылайша, олар кірісте болуы мүмкін және болған жағдайда шығысқа көшіріледі. Бұл ешқандай түсініксіздік тудырмайды: егер шығыста дефистер болса, қосылған дефис әрқашан соңғысы болады. Ол ASCII таңбаларының соңына белгілейді.
ASCII емес таңбаларды кодтау
ASCII емес таңбалар Юникод мәні бойынша реттеледі, ең кішісі бірінші болып келеді (егер бір таңба бірнеше рет кездессе, олар орналасуы бойынша реттеледі). Әрқайсысы жеке сан ретінде кодталады. Бұл бір сан таңбаны қай жерге енгізу керектігін және қандай таңбаны енгізу керектігін анықтайды. *i* – кодты 0-ден бастап (бастапқы орналасу үшін) нәтижеге енгізу индексі. *n* – мүмкін енгізу нүктелерінің саны (нәтижедің қазіргі ұзындығы плюс 1). *j* – енгізілетін Юникодтық код нүктесінен 127-ні шығарылған сан. Кодталған сан *n* × *j* + *i* тең болады. *n*-ге бөліп, қалдықты алу арқылы декодер *j* және *i*-ні анықтай алады. "bcher" жолында таңбаны енгізуге алты мүмкін орын бар (бірінші таңбадан бұрын және соңғы таңбадан кейін қоса алғанда). Соңғы ASCII коды (127 = 0x7F, ASCII-дің соңы) мен "ü" (кодтық нүкте 252 = 0xFC, Unicode-тің Латын 1 қосымшасын қараңыз) арасында 124 кодтық нүкте бар. "ü" әрпі "b" әрпінен кейін 1-орында енгізіледі. Осылайша кодтаушы сандарды қосады, ал декодер оларды және бұл сандар қатаң түрде өседі. Екінші және одан кейінгі енгізілген таңбалар үшін сан мен алдыңғы сан арасындағы айырма жазылады. Сан "a" әрпінен "z" әрпіне дейін және "0" цифрынан "9" цифрына дейін кодталады. Бұл 36-лық санау жүйесі емес, төменде сипатталған күрделі схема, ол сандарды біріктіруге мүмкіндік береді, оларды ешқандай символдар бөліп тұрмайды.
These numbers are strictly increasing. For the second and subsequent inserted characters, the difference between the number and the previous one is written. The number is encoded using the letters "a" through "z" and the digits "0" through "9". It is not base 36 but a more complex scheme described below, which allows the numbers to be concatenated, with nothing separating them.
Түрлі ұзындықтағы санның кодталуы
Punycode осы мәндерді көрсету үшін жалпыланған өзгермелі ұзындығы бар бүтін сандарды қолданады. Мысалы, "kva" 745 кодты бейнелеу үшін қолданылады: бөлек делмитерлерсіз өзгермелі ұзындықтағы кодтарға мүмкіндік беретін кішкентай ендиандық ретпен сандық жүйе қолданылады: шекті мәннен төмен цифр ең маңызды цифр екенін көрсетеді, сондықтан санның соңы. Шекті мән тиімділікті арттыру үшін сандағы орнына және алдыңғы енгізілгендерге байланысты. Осыған сәйкес сандардың салмағы да әр түрлі болады. Бұл жағдайда 36 символы бар сандық жүйе қолданылады, ал әріптерді ерекшелемейтін 'a' мен 'z' аралығындағы әріптер 0 мен 25 аралығындағы ондық сандарға тең, ал '0' мен '9' аралығындағы әріптер 26 мен 35 аралығындағы ондық сандарға тең. Осылайша "kva" ондық сандар тізбегіне сәйкес келеді "10 21 0". Бұл символдар тізбегін кодтау үшін шектер тізбегі қажет болады, бұл жағдайда (1, 1, 26, 26, ). Ең аз маңызды цифрдың салмағы (немесе орындық мәні) әрқашан 1: 'k' (=10) 1 салмағымен 10-ға тең. Бұдан кейін келесі цифрдың салмағы бірінші шекке байланысты: әдетте, кез келген n үшін (n+1)-ші цифрдың салмағы алдыңғы цифрдың салмағына (36 – n-ші цифрдың шегі) көбейтілгенге тең. Екінші символдың орындық мәні 36 минус алдыңғы шекті мән, бұл жағдайда 35. Сондықтан, алғашқы екі символдың қосындысы 'k' (=10) және 'v' (=21) 10 × 1 + 21 × 35 болады. Екінші символ өзінің 1 шекті мәнінен кем емес, сондықтан одан әрі де бар. Алайда, осы мысалдағы үшінші символ 'a' (=0) болғандықтан, оның салмағын есептеуді елемеуге болады. Сондықтан "kva" ондық санды білдіреді (10 × 1) + (21 × 35) = 745. 745 саны 10 + 21 × 35 + 0 (екінші цифр үшін 35-тік база қолданылады, ең маңызды цифр 0 терминатор ретінде қажет), 10 → 'k', 21 → 'v', 0 → 'a', сондықтан "bücher" → "bcher kva". Әрбір кезекті енгізілген таңба үшін шегі 1 мен 26 аралығында алгоритм арқылы анықталады. Бұл жағдайда мәтіннің бастапқы регистрі туралы ақпарат беру үшін қолданылуы мүмкін. Арнайы таңбалар кодтау алгоритмімен кодтық нүктелері бойынша сұрыпталатындықтан, "bücher" кодына екінші арнайы таңбаны енгізу үшін бірінші мүмкіндік "büücher" коды "bcher kvaa", екіншісі "bücüher" коды "bcher kvab" және т.б. "bücherü" коды "bcher kvae" кодынан кейін ý енгізілген кодтар келеді, Unicode таңбасынан кейін ü, "ýbücher" коды "bcher kvaf" (бұған "übücher" коды "bcher jvab") және т.б.
A number system with little endian ordering is used which allows variable length codes without separate delimiters: a digit lower than a threshold value marks that it is the most significant digit, hence the end of the number. The threshold value depends on the position in the number and also on previous insertions, to increase efficiency. Correspondingly the weights of the digits vary. In this case a number system with 36 symbols is used, with the case insensitive 'a' through 'z' equal to the decimal numbers 0 through 25, and '0' through '9' equal to the decimal numbers 26 through 35. Thus "kva", corresponds to the decimal number string "10 21 0". To decode this string of symbols, a sequence of thresholds will be needed, in this case it's (1, 1, 26, 26, ). The weight (or place value) of the least significant digit is always 1: 'k' (=10) with a weight of 1 equals 10. After this, the weight of the next digit depends on the first threshold: generally, for any n, the weight of the (n+1) th digit is the weight of the previous one times (36 − threshold of the n th digit). So the second symbol has a place value of 36 minus the previous threshold value, in this case, 35. Therefore, the sum of the first two symbols 'k' (=10) and 'v' (=21) is 10 × 1 + 21 × 35. Since the second symbol is not less than its threshold value of 1, there is more to come. However, since the third symbol in this example is 'a' (=0), we may ignore calculating its weight. Therefore, "kva" represents the decimal number (10 × 1) + (21 × 35) = 745. Number 745 will be encoded as 10 + 21 × 35 + 0 (base 35 used for second digit, the most significant digit 0 needed as terminator), 10 → 'k', 21 → 'v', 0 → 'a', so "bücher" → "bcher kva". The thresholds themselves are determined for each successive encoded character by an algorithm keeping them between 1 and 26 inclusive. The case can then be used to provide information about the original case of the string. Because special characters are sorted by their code points by encoding algorithm, for the insertion of a second special character in "bücher", the first possibility is "büücher" with code "bcher kvaa", the second "bücüher" with code "bcher kvab", etc. After "bücherü" with code "bcher kvae" comes codes representing insertion of ý, the Unicode character following ü, starting with "ýbücher" with code "bcher kvaf" (different from "übücher" coded "bcher jvab"), etc.
Халықаралық домендік атаулардың ACE префиксі
Халықаралық емес домендік атаулардағы дефистер Punycode декодилеуін тудырмау үшін, интернационалданған домендік атаулардағы Punycode тізбектеріне "xn" тізбегі қосылады. Бұл ACE (ASCII үйлесімді кодтау) деп аталады. Осылайша, "bücher.tld" домендік атауы URL мекенжайында "xn--bcher-kva.tld" түрінде көрсетіледі.
Мысалдар
Келесі кестеде Punycode кодтамаларының түрлі кіріс түрлеріне арналған мысалдар көрсетілген. Кіріс Punycode Сипаттама Бос тізбек. Тек ASCII таңбалары, бір, кіші әріп. Тек ASCII таңбалары, бір, үлкен әріп. Тек ASCII таңбалары, бір, сан. Тек ASCII таңбалары, бір, дефис. Тек ASCII таңбалары, екі дефис. Тек ASCII таңбалары, бірден көп, дефиссіз. Тек ASCII таңбалары, бір дефис. Тек ASCII таңбалары, бос орындармен. Тек ASCII таңбалары, аралас символдар. ASCII таңбалары жоқ, бір кириллица әрпі. ASCII таңбалары жоқ, бір Латын 1 қосымшасы әрпі. ASCII таңбалары жоқ, бір грек әрпі. ASCII таңбалары жоқ, бір CJK әрпі. ASCII таңбалары жоқ, бір эмодзи әрпі. ASCII таңбалары жоқ, бір әріптен артық. Аралас жол, ASCII емес бір әрпімен. "Мюнхен" сөзінің екі рет Punycode кодтамасы. Аралас тізбе, ASCII емес бір әрпі және дефис. Аралас жол, бір бос орын, бір дефис және ASCII емес бір әрпі. Аралас жол, екі ASCII емес әрпі. Орыс тілі, ASCII-сіз. Тай тілі, ASCII-сіз. Корей тілі, ASCII-сіз. Жапон тілі, ASCII-сіз. ASCII-мен жапон тілі. Аралас ASCII емес қаріптер (Латын 1 қосымшасы және CJK).