Punycode
Represents a Punycode encoding helper class.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace AngleSharp.Text
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public static class Punycode
{
private const int PunycodeBase = 36;
private const int Tmin = 1;
private const int Tmax = 26;
private static readonly string acePrefix = "xn--";
private static readonly char[] possibleDots = new char[4] {
'.',
'。',
'.',
'。'
};
public static IDictionary<char, char> Symbols = new Dictionary<char, char> {
{
'。',
'.'
},
{
'.',
'.'
},
{
'G',
'g'
},
{
'o',
'o'
},
{
'c',
'c'
},
{
'X',
'x'
},
{
'0',
'0'
},
{
'1',
'1'
},
{
'2',
'2'
},
{
'5',
'5'
},
{
'⁰',
'0'
},
{
'¹',
'1'
},
{
'²',
'2'
},
{
'³',
'3'
},
{
'⁴',
'4'
},
{
'⁵',
'5'
},
{
'⁶',
'6'
},
{
'⁷',
'7'
},
{
'⁸',
'8'
},
{
'⁹',
'9'
},
{
'₀',
'0'
},
{
'₁',
'1'
},
{
'₂',
'2'
},
{
'₃',
'3'
},
{
'₄',
'4'
},
{
'₅',
'5'
},
{
'₆',
'6'
},
{
'₇',
'7'
},
{
'₈',
'8'
},
{
'₉',
'9'
},
{
'ᵃ',
'a'
},
{
'ᵇ',
'b'
},
{
'ᶜ',
'c'
},
{
'ᵈ',
'd'
},
{
'ᵉ',
'e'
},
{
'ᶠ',
'f'
},
{
'ᵍ',
'g'
},
{
'ʰ',
'h'
},
{
'ⁱ',
'i'
},
{
'ʲ',
'j'
},
{
'ᵏ',
'k'
},
{
'ˡ',
'l'
},
{
'ᵐ',
'm'
},
{
'ⁿ',
'n'
},
{
'ᵒ',
'o'
},
{
'ᵖ',
'p'
},
{
'ʳ',
'r'
},
{
'ˢ',
's'
},
{
'ᵗ',
't'
},
{
'ᵘ',
'u'
},
{
'ᵛ',
'v'
},
{
'ʷ',
'w'
},
{
'ˣ',
'x'
},
{
'ʸ',
'y'
},
{
'ᶻ',
'z'
},
{
'ᴬ',
'A'
},
{
'ᴮ',
'B'
},
{
'ᴰ',
'D'
},
{
'ᴱ',
'E'
},
{
'ᴳ',
'G'
},
{
'ᴴ',
'H'
},
{
'ᴵ',
'I'
},
{
'ᴶ',
'J'
},
{
'ᴷ',
'K'
},
{
'ᴸ',
'L'
},
{
'ᴹ',
'M'
},
{
'ᴺ',
'N'
},
{
'ᴼ',
'O'
},
{
'ᴾ',
'P'
},
{
'ᴿ',
'R'
},
{
'ᵀ',
'T'
},
{
'ᵁ',
'U'
},
{
'ⱽ',
'V'
},
{
'ᵂ',
'W'
}
};
public static string Encode(string text)
{
if (text.Length == 0)
return text;
StringBuilder stringBuilder = new StringBuilder(text.Length);
int num = 0;
int num2 = 0;
int num3 = 0;
while (num < text.Length) {
num = text.IndexOfAny(possibleDots, num2);
if (num < 0)
num = text.Length;
if (num == num2)
break;
stringBuilder.Append(acePrefix);
int num4 = 0;
int num5 = 0;
for (num4 = num2; num4 < num; num4++) {
if (text[num4] < '') {
stringBuilder.Append(EncodeBasic(text[num4]));
num5++;
} else if (char.IsSurrogatePair(text, num4)) {
num4++;
}
}
int num6 = num5;
if (num6 == num - num2)
stringBuilder.Remove(num3, acePrefix.Length);
else {
if (text.Length - num2 >= acePrefix.Length && text.Substring(num2, acePrefix.Length).Isi(acePrefix))
break;
int num7 = 0;
if (num6 > 0)
stringBuilder.Append('-');
int num8 = 128;
int num9 = 0;
int num10 = 72;
while (num5 < num - num2) {
int num11 = 0;
int num12 = 0;
int num13 = 0;
num12 = 134217727;
for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2)) {
num13 = char.ConvertToUtf32(text, num11);
if (num13 >= num8 && num13 < num12)
num12 = num13;
}
num9 += (num12 - num8) * (num5 - num7 + 1);
num8 = num12;
for (num11 = num2; num11 < num; num11 += ((!IsSupplementary(num13)) ? 1 : 2)) {
num13 = char.ConvertToUtf32(text, num11);
if (num13 < num8)
num9++;
else if (num13 == num8) {
int num14 = num9;
int num15 = 36;
while (true) {
int num16 = (num15 <= num10) ? 1 : ((num15 >= num10 + 26) ? 26 : (num15 - num10));
if (num14 < num16)
break;
stringBuilder.Append(EncodeDigit(num16 + (num14 - num16) % (36 - num16)));
num14 = (num14 - num16) / (36 - num16);
num15 += 36;
}
stringBuilder.Append(EncodeDigit(num14));
num10 = AdaptChar(num9, num5 - num7 + 1, num5 == num6);
num9 = 0;
num5++;
if (IsSupplementary(num12)) {
num5++;
num7++;
}
}
}
num9++;
num8++;
}
}
if (stringBuilder.Length - num3 > 63)
throw new ArgumentException();
if (num != text.Length)
stringBuilder.Append(possibleDots[0]);
num2 = num + 1;
num3 = stringBuilder.Length;
}
int num17 = (!IsDot(text[text.Length - 1])) ? 1 : 0;
int num18 = 255 - num17;
if (stringBuilder.Length > num18)
stringBuilder.Remove(num18, stringBuilder.Length - num18);
return stringBuilder.ToString();
}
private static bool IsSupplementary(int test)
{
return test >= 65536;
}
private static bool IsDot(char c)
{
for (int i = 0; i < possibleDots.Length; i++) {
if (possibleDots[i] == c)
return true;
}
return false;
}
private static char EncodeDigit(int digit)
{
if (digit > 25)
return (char)(digit + 22);
return (char)(digit + 97);
}
private static char EncodeBasic(char character)
{
if (char.IsUpper(character))
character = (char)(character + 32);
return character;
}
private static int AdaptChar(int delta, int numPoints, bool firstTime)
{
uint num = 0;
delta = (firstTime ? (delta / 700) : (delta / 2));
delta += delta / numPoints;
num = 0;
while (delta > 455) {
delta /= 35;
num += 36;
}
return (int)(num + 36 * delta / (delta + 38));
}
}
}