- Сообщения
 - 8,143
 
- Решения
 - 27
 
- Реакции
 - 6,959
 
Причиной разобраться в том, как же работает UTF-8 и что такое Юникод заставил тот факт, что VBScript не имеет встроенных функций работы с UTF-8. А так как ничего рабочего не нашел, то пришлось писать/дописывать самому. Опыт на мой взгляд полезный в любом случае. Для лучшего понимания начну с теории.
О Юникоде
До появления Юникода широко использовались 8-битные кодировки, главные минусы которых очевидны:
Так и было решено создать единый стандарт «широкой» кодировки, которая включала бы все символы (при чем сначала хотели в нее включить только обычные символы, но потом передумали и начали добавлять и экзотические). Юникод использует 1 112 064 кодовых позиций (больше чем 16 бит). Начало дублирует ASCII, а дальше остаток латиницы, кирилица, другие европейские и азиатские символы. Для обозначений символов используют шестнадцатеричную запись вида «U+xxxx» для первых 65k и с большим количеством цифр для остальных.
О UTF-8
Когда-то я думал что есть Юникод, а есть UTF-8. Позже я узнал, что ошибался.
UTF-8 является лишь представлением Юникода в 8-битном виде. Символы с кодами меньше 128 представляются одним байтом, а так как в Юникоде они повторяют ASCII, то текст написанный только этими символами будет являться текстом в ASCII. Символы же с кодами от 128 кодируются 2-мя байтами, с кодами от 2048 — 3-мя, от 65536 — 4-мя. Так можно было бы и до 6-ти байт дойти, но кодировать ими уже ничего.
0x00000000 — 0x0000007F: 0xxxxxxx
0x00000080 — 0x000007FF: 110xxxxx 10xxxxxx
0x00000800 — 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
0x00010000 — 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Кодируем в UTF-8
Порядок действий примерно такой:
	
	
		
			
	
	
	
		
		
	
Декодируем UTF-8
	
	
		
			
	
	
	
		
		
	
По теме:
Юникод на Википедии
Источник
	
		
			
		
		
	
				
			О Юникоде
До появления Юникода широко использовались 8-битные кодировки, главные минусы которых очевидны:
- Всего 255 символов, да и то часть из них не графические;
 - Возможность открыть документ не с той кодировкой, в которой он был создан;
 - Шрифты необходимо создавать для каждой кодировки.
 
Так и было решено создать единый стандарт «широкой» кодировки, которая включала бы все символы (при чем сначала хотели в нее включить только обычные символы, но потом передумали и начали добавлять и экзотические). Юникод использует 1 112 064 кодовых позиций (больше чем 16 бит). Начало дублирует ASCII, а дальше остаток латиницы, кирилица, другие европейские и азиатские символы. Для обозначений символов используют шестнадцатеричную запись вида «U+xxxx» для первых 65k и с большим количеством цифр для остальных.
О UTF-8
Когда-то я думал что есть Юникод, а есть UTF-8. Позже я узнал, что ошибался.
UTF-8 является лишь представлением Юникода в 8-битном виде. Символы с кодами меньше 128 представляются одним байтом, а так как в Юникоде они повторяют ASCII, то текст написанный только этими символами будет являться текстом в ASCII. Символы же с кодами от 128 кодируются 2-мя байтами, с кодами от 2048 — 3-мя, от 65536 — 4-мя. Так можно было бы и до 6-ти байт дойти, но кодировать ими уже ничего.
0x00000000 — 0x0000007F: 0xxxxxxx
0x00000080 — 0x000007FF: 110xxxxx 10xxxxxx
0x00000800 — 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
0x00010000 — 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Кодируем в UTF-8
Порядок действий примерно такой:
- Каждый символ превращаем в Юникод.
 - Проверяем из какого символ диапазона.
 - Если код символа меньше 128, то к результату добавляем его в неизменном виде.
 - Если код символа меньше 2048, то берем последние 6 бит и первые 5 бит кода символа. К первым 5 битам добавляем 0xC0 и получаем первый байт последовательности, а к последним 6 битам добавляем 0x80 и получаем второй байт. Конкатенируем и добавляем к результату.
 - Похожим образом можем продолжить и для больших кодов, но если символ за пределами U+FFFF придется иметь дело с UTF-16 суррогатами.
 
		VB.NET / VBA:
	
	
	Function EncodeUTF8(s)
    Dim i, c, utfc, b1, b2, b3
    For i=1 to Len(s)
        c = ToLong(AscW(Mid(s,i,1)))
 
        If c < 128 Then
            utfc = chr( c)
        ElseIf c < 2048 Then
            b1 = c Mod &h40
            b2 = (c - b1) / &h40
            utfc = chr(&hC0 + b2) & chr(&h80 + b1)
        ElseIf c < 65536 And (c < 55296 Or c > 57343) Then
            b1 = c Mod &h40
            b2 = ((c - b1) / &h40) Mod &h40
            b3 = (c - b1 - (&h40 * b2)) / &h1000
            utfc = chr(&hE0 + b3) & chr(&h80 + b2) & chr(&h80 + b1)
        Else
            ' Младший или старший суррогат UTF-16
            utfc = Chr(&hEF) & Chr(&hBF) & Chr(&hBD)
        End If
 
        EncodeUTF8 = EncodeUTF8 + utfc
    Next
End Function
Function ToLong(intVal)
    If intVal < 0 Then
        ToLong = CLng(intVal) + &H10000
    Else
        ToLong = CLng(intVal)
    End If
End Function
	Декодируем UTF-8
- Ищем первый символ вида 11xxxxxx
 - Считаем все последующие байты вида 10xxxxxx
 - Если последовательность из двух байт и первый байт вида 110xxxxx, то отсекаем приставки и складываем, умножив первый байт на 0x40.
 - Аналогично для более длинных последовательностей.
 - Заменяем всю последовательность на нужный символ Юникода.
 
		VB.NET / VBA:
	
	
	Function DecodeUTF8(s)
    Dim i, c, n, b1, b2, b3
 
    i = 1
        Do While i <= len(s)
            c = asc(mid(s,i,1))
            If (c and &hC0) = &hC0 Then
                n = 1
                Do While i + n <= len(s)
                    If (asc(mid(s,i+n,1)) and &hC0) <> &h80 Then
                        Exit Do
                    End If
                    n = n + 1
                Loop
                If n = 2 and ((c and &hE0) = &hC0) Then
                    b1 = asc(mid(s,i+1,1)) and &h3F
                    b2 = c and &h1F
                    c = b1 + b2 * &h40
                Elseif n = 3 and ((c and &hF0) = &hE0) Then
                    b1 = asc(mid(s,i+2,1)) and &h3F
                    b2 = asc(mid(s,i+1,1)) and &h3F
                    b3 = c and &h0F
                    c = b3 * &H1000 + b2 * &H40 + b1
                Else
                    ' Символ больше U+FFFF или неправильная последовательность
                    c = &hFFFD
                End if
                s = left(s,i-1) + chrw( c) + mid(s,i+n)
            Elseif (c and &hC0) = &h80 then
                ' Неожидаемый продолжающий байт
                s = left(s,i-1) + chrw(&hFFFD) + mid(s,i+1)
            End If
            i = i + 1
        Loop
    DecodeUTF8 = s
End Function
	По теме:
Юникод на Википедии
Источник
			
				Последнее редактирование: 
			
		
	
								
								
									
	
		
			
		
		
	
	
	
		
			
		
		
	
								
							
							