Golang windows 1251 to utf 8

Работа с кодировкой UTF-8 в Golang. Изменение кодировки строк символов в Golang в UTF-8. Использование Charmap для изменения кодировки.

Всегда нужно быть готовым к тому, что кодировка входных данных из разных источников может различаться. Конечно, большинство используют операционную систему Windows, но не только. Go по умолчанию предполагает, что строки в программах будут в кодировке UTF-8. Если это не так, тогда их требуется декодировать, чтобы в дальнейшем можно было с ними работать. В данной инструкции показано, как читать и записывать файлы в других кодировках, помимо UTF-8.

Как использовать разные кодировками в Golang?

1. Создайте файл charset.go со следующим содержимым:

Премиум 👑 канал по Golang

Рекомендуем вам супер TELEGRAM канал по Golang где собраны все материалы для качественного изучения языка. Удивите всех своими знаниями на собеседовании! 😎

Подписаться на канал

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

Go в ВК

ЧАТ в Telegram

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

package main

import (

«fmt»

«io/ioutil»

«os»

«golang.org/x/text/encoding/charmap»

)

func main() {

// Запись строки в кодировке Windows-1252

encoder := charmap.Windows1252.NewEncoder()

s, e := encoder.String(«This is sample text with runes Š»)

if e != nil {

panic(e)

}

ioutil.WriteFile(«example.txt», []byte(s), os.ModePerm)

// Декодировка в UTF-8

f, e := os.Open(«example.txt»)

if e != nil {

panic(e)

}

defer f.Close()

decoder := charmap.Windows1252.NewDecoder()

reader := decoder.Reader(f)

b, err := ioutil.ReadAll(reader)

if err != nil {

panic(err)

}

fmt.Println(string(b))

}

2. Запустите код через go run charset.go;
3. Посмотрите на результат в терминале:

This is sample text with runes Š

Конвертирование кодировки Windows-1251 в UTF-8

Пакет golang.org/x/text/encoding/charmap содержит константы типа указателя Charmap, что представляют наиболее часто используемые кодировки. Тип Charmap предоставляет методы для создания кодера и декодера для определенного набора символов. Encoder создает Writer для кодировки, что кодирует записанные байты в выбранную кодировку. Также Decoder может создать Reader для декодировки, что декодирует все данные для чтения из выбранной кодировки.

Также можете ознакомиться с инструкцией для изменения кодировки строки, символы которой не относятся к Unicode.

Администрирую данный сайт с целью распространения как можно большего объема обучающего материала для языка программирования Go. В IT с 2008 года, с тех пор изучаю и применяю интересующие меня технологии. Проявляю огромный интерес к машинному обучению и анализу данных.

E-mail: vasile.buldumac@ati.utm.md

Образование

Технический Университет Молдовы (utm.md), Факультет Вычислительной Техники, Информатики и Микроэлектроники

  • 2014 — 2018 Universitatea Tehnică a Moldovei, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Universitatea Tehnică a Moldovei, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»

cpp

Преобразование кодировок

До этого момента мы работали с файлами в кодировке UTF-8. Однако файлы могут быть в различных кодировках. Например, в русской версии Windows файлы чаще всего сохранены в кодировке windows-1251. Чтобы иметь возможность выполнять преобразование кодировок нужно установить дополнительный пакет. Переходим в проект C:bookpackages и выполняем следующую команду:

C:bookpackages>go get -u golang.org/x/text
go get: added golang.org/x/text v0.3.7

Обратите внимание на содержимое файла go.mod, там появилась зависимость:

module exanple.com/mymodule

go 1.17

require golang.org/x/text v0.3.7 // indirect

Русские кодировки

Подключение пакета, предназначенного для преобразования кодировок, выглядит так:

import "golang.org/x/text/encoding/charmap"

Пакет содержит следующие основные объекты русских кодировок (полный список смотрите в документации):

var charmap.Windows1251 *charmap.Charmap
var charmap.CodePage866 *charmap.Charmap
var charmap.KOI8R *charmap.Charmap

Структура Charmap содержит два основных метода:

(*charmap.Charmap).NewEncoder() *encoding.Encoder
(*charmap.Charmap).NewDecoder() *encoding.Decoder

С помощью структуры Encoder выполняется преобразование данных из кодировки UTF-8 в кодировку объекта структуры Charmap. Структура Encoder содержит следующие методы:

  • String() — выполняет преобразование кодировки строки. Формат метода:
(*encoding.Encoder).String(s string) (string, error)

Метод возвращает два значения. Через первое значение доступна преобразованная строка. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример преобразования строки в кодировке UTF-8 в строку в кодировке windows-1251:

// import "golang.org/x/text/encoding/charmap"
utf8 := "строка"
encoder := charmap.Windows1251.NewEncoder()
win1251, err := encoder.String(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println([]byte(win1251)) // [241 242 240 238 234 224]
  • Bytes() — выполняет преобразование кодировки байтового слайса. Формат метода:
(*encoding.Encoder).Bytes(b []byte) ([]byte, error)

Метод возвращает два значения. Через первое значение доступен преобразованный байтовый слайс. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример:

utf8 := []byte("строка")
encoder := charmap.Windows1251.NewEncoder()
win1251, err := encoder.Bytes(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(win1251) // [241 242 240 238 234 224]
  • Writer() — возвращает объект io.Writer с помощью которого можно записывать преобразованные данные в поток вывода. Формат метода:
(*encoding.Encoder).Writer(w io.Writer) io.Writer

Пример записи строки в файл в кодировке windows-1251:

func test() {
   file, err := os.Create(`C:booktest.txt`)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer file.Close()
   encoder := charmap.Windows1251.NewEncoder()
   win1251 := encoder.Writer(file)
   _, err = io.WriteString(win1251, "Строка1nСтрока2")
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println("Операция выполнена успешно")
}

С помощью структуры Decoder выполняется преобразование данных из кодировки объекта структуры Charmap в кодировку UTF-8. Структура Decoder содержит следующие методы:

  • String() — выполняет преобразование кодировки строки. Формат метода:
(*encoding.Decoder).String(s string) (string, error)

Метод возвращает два значения. Через первое значение доступна преобразованная строка. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример преобразования строки в кодировке windows-1251 в строку в кодировке UTF-8:

// import "golang.org/x/text/encoding/charmap"
win1251 := "xf1xf2xf0xeexeaxe0"
decoder := charmap.Windows1251.NewDecoder()
utf8, err := decoder.String(win1251)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(utf8) // строка
  • Bytes() — выполняет преобразование кодировки байтового слайса. Формат метода:
(*encoding.Decoder).Bytes(b []byte) ([]byte, error)

Метод возвращает два значения. Через первое значение доступен преобразованный байтовый слайс. Через второе значение доступен объект ошибки или nil, если операция выполнена успешно. Пример:

win1251 := []byte{241, 242, 240, 238, 234, 224}
decoder := charmap.Windows1251.NewDecoder()
utf8, err := decoder.Bytes(win1251)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(string(utf8)) // строка
  • Reader() — возвращает объект io.Reader с помощью которого можно считывать преобразованные данные из потока ввода. Формат метода:
(*encoding.Decoder).Reader(r io.Reader) io.Reader

Пример чтения из файла, сохраненного в кодировке windows-1251:

func test() {
   file, err := os.Open(`C:booktest.txt`)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer file.Close()
   decoder := charmap.Windows1251.NewDecoder()
   win1251 := decoder.Reader(file)
   utf8, err := io.ReadAll(win1251)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(utf8))
}

Кодировка UTF-16

Для работы с кодировкой UTF-16 нужно использовать функцию UTF16() из пакета golang.org/x/text/encoding/unicode. Формат функции:

unicode.UTF16(e unicode.Endianness,
              b unicode.BOMPolicy) encoding.Encoding

Первый параметр задает порядок следования байтов. Можно указать константы unicode.LittleEndian или unicode.BigEndian. Второй параметр задает политику обработки метки порядка байтов (BOM). Можно указать следующие константы:

  • unicode.UseBOM — метка порядка байтов используется;
  • unicode.IgnoreBOM — метка порядка байтов игнорируется;
  • unicode.ExpectBOM — метка порядка байтов используется для переопределения кодировки по умолчанию.

Функция UTF16() возвращает объект Encoding, который содержит знакомые уже нам методы:

(encoding.Encoding).NewEncoder() *encoding.Encoder
(encoding.Encoding).NewDecoder() *encoding.Decoder

Пример преобразования строки в кодировке UTF-8 в строку в кодировке UTF-16LE с BOM:

// import "golang.org/x/text/encoding/unicode"
utf8 := "строка"
encoder := unicode.UTF16(unicode.LittleEndian,
                         unicode.UseBOM).NewEncoder()
utf16le, err := encoder.String(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println([]byte(utf16le))
// [255 254 65 4 66 4 64 4 62 4 58 4 48 4]

Пример преобразования строки в кодировке UTF-16LE в строку в кодировке UTF-8:

utf16le := "xffxfeAx04Bx04@x04>x04:x040x04"
decoder := unicode.UTF16(unicode.LittleEndian,
                         unicode.UseBOM).NewDecoder()
utf8, err := decoder.String(utf16le)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(utf8) // строка

Кодировка UTF-32

Для работы с кодировкой UTF-32 нужно использовать функцию UTF32() из пакета golang.org/x/text/encoding/unicode/utf32. Формат функции:

utf32.UTF32(e utf32.Endianness, b utf32.BOMPolicy) encoding.Encoding

Первый параметр задает порядок следования байтов. Можно указать константы utf32.LittleEndian или utf32.BigEndian. Второй параметр задает политику обработки метки порядка байтов (BOM). Можно указать следующие константы:

  • utf32.UseBOM — метка порядка байтов используется;
  • utf32.IgnoreBOM — метка порядка байтов игнорируется;
  • utf32.ExpectBOM — метка порядка байтов используется для переопределения кодировки по умолчанию.

Функция UTF32() возвращает объект Encoding, который содержит знакомые уже нам методы:

(encoding.Encoding).NewEncoder() *encoding.Encoder
(encoding.Encoding).NewDecoder() *encoding.Decoder

Пример преобразования строки в кодировке UTF-8 в строку в кодировке UTF-32LE с BOM:

// import "golang.org/x/text/encoding/unicode/utf32"
utf8 := "тест"
encoder := utf32.UTF32(utf32.LittleEndian,
                       utf32.UseBOM).NewEncoder()
utf32le, err := encoder.String(utf8)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println([]byte(utf32le))
// [255 254 0 0 66 4 0 0 53 4 0 0 65 4 0 0 66 4 0 0]

Пример преобразования строки в кодировке UTF-32LE в строку в кодировке UTF-8:

utf32le := "xffxfex00x00Bx04x00x005x04x00x00Ax04" +
           "x00x00Bx04x00x00"
decoder := utf32.UTF32(utf32.LittleEndian,
                       utf32.UseBOM).NewDecoder()
utf8, err := decoder.String(utf32le)
if err != nil {
   fmt.Println(err)
   return
}
fmt.Println(utf8) // тест

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF


This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters

Show hidden characters

package main
import (
«fmt»
«golang.org/x/text/encoding/charmap»
)
func main() {
for i := 0; i <= 255; i++ {
charnum := uint8(i)
orig := []uint8{charnum}
utf8 := DecodeWindows1251(orig)
win1251 := EncodeWindows1251(utf8)
if string(orig) != string(win1251) {
fmt.Printf(«Oh~.. Failed at charnum 0x%xn«, i)
fmt.Printf(«(orig, utf8, win1251)n«)
fmt.Printf(«string: %s, %s, %sn«, string(orig), string(utf8), string(win1251))
fmt.Printf(«quoted: %+q, %+q, %+qn«, string(orig), string(utf8), string(win1251))
fmt.Printf(«hex : % x, % x, % xn«, string(orig), string(utf8), string(win1251))
}
}
}
func DecodeWindows1251(ba []uint8) []uint8 {
dec := charmap.Windows1251.NewDecoder()
out, _ := dec.Bytes(ba)
return out
}
func EncodeWindows1251(ba []uint8) []uint8 {
enc := charmap.Windows1251.NewEncoder()
out, _ := enc.String(string(ba))
return []uint8(out)
}

I checked out the docs, here, and I came up with a way to convert an array of bytes to (or from) UTF-8.

What I have a hard time with is that, so far, I’ve not found an interface that would allow me to use a locale. Instead, it’s like the possible ways are limited to predefined sets of encodings.

In my case, I needed to convert UTF-16 (really I have USC-2 data, but it should still work) to UTF-8. To do that, I needed to check for the BOM and then do the conversion:

bom := buf[0] + buf[1] * 256
if bom == 0xFEFF {
    enc = unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
} else if bom == 0xFFFE {
    enc = unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM)
} else {
    return Error("BOM missing")
}

e := enc.NewDecoder()

// convert USC-2 (LE or BE) to UTF-8
utf8 := e.Bytes(buf[2:])

Unfortunate that I have to use «ignore» BOM since in my case it should instead be forbidden past the first character. But that’s close enough for my situation. These functions were mentioned in a couple of places, but not shown in practice.

  • Variables
  • func ANY_to_UTF8(src []byte, charset string) ([]byte, error)
  • func CP1250_to_UTF8(src []byte) []byte
  • func CP1251_to_UTF8(src []byte) []byte
  • func CP1252_to_UTF8(src []byte) []byte
  • func CP852_to_UTF8(src []byte) []byte
  • func CP855_to_UTF8(src []byte) []byte
  • func CP866_to_UTF8(src []byte) []byte
  • func ISO88595_to_UTF8(src []byte) []byte
  • func KOI8R_to_UTF8(src []byte) []byte
  • func KOI8U_to_UTF8(src []byte) []byte
  • func ToUTF8(table *DecodeTable, src []byte) []byte
  • type DecodeTable

This section is empty.

View Source

var KnownCharsets = map[string](*DecodeTable){
	"CP1250":       &CP1250_UTF8_TABLE,
	"cp1250":       &CP1250_UTF8_TABLE,
	"WINDOWS-1250": &CP1250_UTF8_TABLE,
	"windows-1250": &CP1250_UTF8_TABLE,

	"CP1251":       &CP1251_UTF8_TABLE,
	"cp1251":       &CP1251_UTF8_TABLE,
	"WINDOWS-1251": &CP1251_UTF8_TABLE,
	"windows-1251": &CP1251_UTF8_TABLE,

	"CP1252":       &CP1252_UTF8_TABLE,
	"cp1252":       &CP1252_UTF8_TABLE,
	"WINDOWS-1252": &CP1252_UTF8_TABLE,
	"windows-1252": &CP1252_UTF8_TABLE,

	"CP852":  &CP852_UTF8_TABLE,
	"cp852":  &CP852_UTF8_TABLE,
	"IBM852": &CP852_UTF8_TABLE,
	"ibm852": &CP852_UTF8_TABLE,

	"CP855":  &CP855_UTF8_TABLE,
	"cp855":  &CP855_UTF8_TABLE,
	"IBM855": &CP855_UTF8_TABLE,
	"ibm855": &CP855_UTF8_TABLE,

	"CP866":  &CP866_UTF8_TABLE,
	"cp866":  &CP866_UTF8_TABLE,
	"IBM866": &CP866_UTF8_TABLE,
	"ibm866": &CP866_UTF8_TABLE,

	"KOI8-R": &KOI8R_UTF8_TABLE,
	"KOI8R":  &KOI8R_UTF8_TABLE,
	"koi8-r": &KOI8R_UTF8_TABLE,
	"koi8r":  &KOI8R_UTF8_TABLE,

	"KOI8-U": &KOI8U_UTF8_TABLE,
	"KOI8U":  &KOI8U_UTF8_TABLE,
	"koi8-u": &KOI8U_UTF8_TABLE,
	"koi8u":  &KOI8U_UTF8_TABLE,

	"ISO-8859-5": &ISO88595_UTF8_TABLE,
	"ISO8859-5":  &ISO88595_UTF8_TABLE,
	"iso-8859-5": &ISO88595_UTF8_TABLE,
	"iso8859-5":  &ISO88595_UTF8_TABLE,
}

func ISO88595_to_UTF8(src []byte) []byte

Пишу парсер для xml файлов, но проблема в том, что в файле кодировка:
encoding=»windows-1251″.
Когда перевел кодировку в ut8 то следующем кодом смог распарсить документ.

for _, file := range files {
            _, filename := utils.Unzip("/Users/farex/upload/"+file.Filename, "/Users/farex/upload/")
            _ = filename
            ///---------- Open our xmlFile-----------------------
            for _, file := range filename {
                xmlFile, err := os.Open("/Users/farex/upload/" + file)
                // if we os.Open returns an error then handle it
                if err != nil {
                    fmt.Println(err)
                }
                fmt.Println("Successfully Opened " + file)

                if utils.Cut(file, 1) == "H" {

                    defer xmlFile.Close()

                    byteValue, _ := ioutil.ReadAll(xmlFile)
                    var zl_list models.ZL_LIST

                    xml.Unmarshal(byteValue, &zl_list)

                    fmt.Println("---ZGLV---")
                    fmt.Println("VERSION" + zl_list.ZGLV[0].VERSION)
                    fmt.Println("DATA" + zl_list.ZGLV[0].DATA)
                    fmt.Println("FILENAME" + zl_list.ZGLV[0].FILENAME)
                    fmt.Println("SD_z" + zl_list.ZGLV[0].SD_Z)

Это все работает, но задача парсить не Документы в формате utf8 , а в cp-1251.
Как можно «конвертировать» cp-1251 в utf-8 ?
Добавил меторд:

func EncodeWindows1251(ba []uint8) []uint8 {
    enc := charmap.Windows1251.NewEncoder()
    out, _ := enc.String(string(ba))
    return []uint8(out)
}

и соответственно вызываю его:

byteValue, _ := ioutil.ReadAll(xmlFile)
a := EncodeWindows1251(byteValue)
var zl_list  models.ZL_LIST
xml.Unmarshal(a, &zl_list)

Тоже не работает…
Но если из документа убрать строку <?xml version="1.0" encoding="windows-1251"?>.
То все работает и документ парсится… Неужели придется регуляркой удалять эту строчку в документе?

Добавил метод наисанный ниже и за импортировал. «golang.org/x/text/encoding/charmap».
Но:
введите сюда описание изображения

Образец файла xml тут кодировка cp-1251

Mar 9 2016


At one point or another, every developer gets stuck converting a pile of files from one character encoding to another. Go’s native character set is UTF-8, and the core Go libraries don’t come with tools for converting character sets. However, one of the Go extension libraries makes this easy.

The package you want is golang.org/x/text, which comes with a variety of tools for working with text. And the one we’re most interested in is the encoding set of packages.

Decode to UTF-8, Encode to Something Else

The encoding library defines Decoder and Encoder structs.

  • The Decoder is used for starting with text in a non-UTF-8 character set, and transforming the source text to UTF-8 text.
  • The Encoder is used to take UTF-8 text and transform it to another encoding.

Particular encodings are stored in a number of subpackages beneath golang.org/x/text/encoding.

One of the most widely used encodings in the North America and Europe is ISO-8859-1 (aka Latin-1). So here we’ll show how to decode from that format into UTF-8.

A number of common Western encodings are located in the golang.org/x/text/encoding/charmap package. This includes the ISO-8859 family as well as the Windows 1252 character set.

package main

import (
    "io"
    "os"

    "golang.org/x/text/encoding/charmap"
)

func main() {
    f, err := os.Open("my_isotext.txt")
    if err != nil {
        // handle file open error
    }
    out, err := os.Create("my_utf8.txt")
    if err != nil {
        // handler error
    }

    r := charmap.ISO8859_1.NewDecoder().Reader(f)

    io.Copy(out, r)

    out.Close()
    f.Close()
}

The above opens a ISO-8859-1 source text (my_isotext.txt), creates a destination file (my_utf.txt), and copies the first to the second. But to decode from ISO-8859-1 to UTF-8, we wrap the original file reader (f) with a decoder:

r := charmap.ISO8859_1.NewDecoder().Reader(f)

Decoding happens as we stream data from the source file to the destination.

From the command line, we can see the result:

⇒  go run main.go
⇒  file my_isotext.txt
my_isotext.txt: ISO-8859 English text, with CRLF line terminators
⇒  file my_utf8.txt
my_utf8.txt: UTF-8 Unicode English text, with CRLF line terminators

Decoders and encoders can also work with strings and []byte, making them versatile whatever your encoding needs are.


  • go
  • golang
  • goquickly
  • gohack

In this blog, we will learn about the Golang UTF8 Package and Character Encoding in Programming Languages.

The Golang Unicode/utf8 package provides several useful functions for querying and manipulating strings and []bytes which hold UTF8 bytes.

First of all, let’s understand the difference between UTF8 and ASCII Encoding.

ASCII vs UTF8 Encoding

In earlier days of the invention of programming language, the computer scientists felt the need for only 128 characters and thus they encoded the 128 characters in 1 byte (primarily 7 bits, as the starting 1 bit is only for signal).

2^7 = 128

This Encoding was called ASCII (American Standard Code for Information Interchange).

ASCII Example:

A (Capital) has an ASCII value of 65 – Binary representation of A is: 1000001

01000001

while nowadays, we use a lot of characters and many countries type code in their own native language other than English than how it’s possible.

Unicode is a standard that encodes almost all the characters used in the world for convenience purposes. The UTF8 (8-bit Unicode Transformation Format) defined by Unicode Standards, is a character encoding that encodes a total of 1,112,064 characters.

The UTF8 is developed by Ken Thompson and Rob Pike (also developers of The GO Programming language). This is also the reason why Golang is typed in UTF8 Encoding.

UTF8 is a variable width character encoding, and uses one – four bytes to encode a character. UTF8 Supports ASCII as it is backward compatible. As ASCII Characters take only 7 bits or 1 byte to encode a character, it is given first place in the UTF8 Encoding.

Other Characters take two four bytes in order to encode.

The Characters take two or more bytes for UTF8 encoding, there is a similarity, the first bit is preceded by as many ones as the characters encoding size and a Zero. Example.

Byte1 = 110xxxxx

After that, all the bytes get preceded by 10s.

Byte2 = 10xxxxxx

Visit the Wikipedia page to know more about UTF8 Encoding.

Devanagari (Hindi) UTF8 Code

In this blog, I will be using examples in Hindi as well as English Unicodes, Take a reference for Devanagri UTF8 Code.

Golang UTF8 Package DecodeRune

func DecodeRune(p []byte) (r rune, size int)

Decode Rune takes the first UTF8 encoding from the passed string and returns rune of the encoded character and the size it takes in UTF8 encoding.

If the passed string is empty, the DecodeRune function returns rune error and 0 as the size of the encoded character. If the encoded string is invalid then the function returns rune error and 1.

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	str := []byte("नमस्ते दुनिया") // Hello World in Hindi

	for len(b) > 0 {
		r, size := utf8.DecodeRune(str)
		fmt.Printf("%c %v bytesn", r, size)

		str = str[size:]
	}
}

Output:

न 3 bytes
म 3 bytes
स 3 bytes
् 3 bytes
त 3 bytes
े 3 bytes
1 bytes
द 3 bytes
ु 3 bytes
न 3 bytes
ि 3 bytes
य 3 bytes
ा 3 bytes

DecodeRuneInString

func DecodeRuneInString(s string) (r rune, size int)

Golang UTF8 Package DecodeRuneInString function is like DecodeRune but its input is a string.

Golang UTF8 Package DecodeLastRune

func DecodeLastRune(p []byte) (r rune, size int)

Golang UTF8 Package DecodeLastRune function takes the last UTF8 encoding from the passed string, and returns rune of the encoded character and the size it takes in UTF8 encoding.

If the string is empty DecodeLastRune function returns (RuneError, 0).

Otherwise, if the encoding is invalid, the function returns (RuneError, 1).

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	str := []byte("नमस्ते दुनिया") // Hello World in Hindi

	for len(b) > 0 {
		r, size := utf8.DecodeLastRune(str)
		fmt.Printf("UTF8 Code: %v %c %v bytesn", r, r, size)

		str = str[:len(str)-size]
	}
}
UTF8 Code: 2366 ा 3 bytes
UTF8 Code: 2351 य 3 bytes
UTF8 Code: 2367 ि 3 bytes
UTF8 Code: 2344 न 3 bytes
UTF8 Code: 2369 ु 3 bytes
UTF8 Code: 2342 द 3 bytes
UTF8 Code: 32   1 bytes
UTF8 Code: 2375 े 3 bytes
UTF8 Code: 2340 त 3 bytes
UTF8 Code: 2381 ् 3 bytes
UTF8 Code: 2360 स 3 bytes
UTF8 Code: 2350 म 3 bytes
UTF8 Code: 2344 न 3 bytes

DecodeLastRuneInString

func DecodeLastRuneInString(s string) (r rune, size int)

Golang UTF8 Package DecodeLastRuneInString function is like DecodeLastRune but its input is a string.

Example:

	str := "नमस्ते दुनिया" // Hello World in Hindi

	for len(str) > 0 {
		r, size := utf8.DecodeLastRuneInString(str)
		fmt.Printf("UTF8 Code: %v %c %v bytesn", r, r, size)

		str = str[:len(str)-size]
	}
UTF8 Code: 2366 ा 3 bytes
UTF8 Code: 2351 य 3 bytes
UTF8 Code: 2367 ि 3 bytes
UTF8 Code: 2344 न 3 bytes
UTF8 Code: 2369 ु 3 bytes
UTF8 Code: 2342 द 3 bytes
UTF8 Code: 32   1 bytes
UTF8 Code: 2375 े 3 bytes
UTF8 Code: 2340 त 3 bytes
UTF8 Code: 2381 ् 3 bytes
UTF8 Code: 2360 स 3 bytes
UTF8 Code: 2350 म 3 bytes
UTF8 Code: 2344 न 3 bytes

Golang UTF8 Package EncodeRune

func EncodeRune(b []byte, r rune) int

The EncodeRune Function takes a byte array and a rune and encodes it to UTF8 Encoding.

Example:

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	r := 'क' // English K
	b := make([]byte, 3)

	n := utf8.EncodeRune(b, r)

	fmt.Print("Byte Array :",b)
	fmt.Print("Number of Bytes Written:",n)
}

Output:

Byte Array : [224 164 149] Number of Bytes Written: 3

Explanation:

The Hindi letter (DEVANAGARI LETTER KA) UTF8 encoding takes 3 bytes. The output returns the bytes of the letter. Let’s dive deeper into the binary and know how the letter is encoded in UTF8.

Binary of 224:

11100000

Binary of 164:

10100100

Binary of 149:

10010101

According to the UTF8 Encoding Rule, the first byte (except any ASCII Characters) is preceded by the number of ones equal to the size of that character and next 0, and the rest of the bytes will precede with 10s, this is a fixed rule for UTF8 Encoding.

Golang UTF8 RuneCount

func RuneCount(b []byte) int

Golang UTF8 RuneCount function returns the number of runes in an array of bytes.

Example:

func main() {
	b := []byte("Hello, दुनिया") // World in Hindi
	fmt.Println(b)
	fmt.Println("bytes =", len(b))
	fmt.Println("runes =", utf8.RuneCount(b))
}

Output:

[72 101 108 108 111 44 32 224 164 166 224 165 129 224 164 168 224 164 191 224 164 175 224 164 190]bytes = 25
runes = 13

In the output, the bytes array contains 25 elements but there are only a few when we look at it.

The byte array, from 72 to 32 it contains the “Hello,” String and after that contains the byte for UTF8 Encoded string.

The reason why the string splits into a long byte array as each character takes 3 bytes to encode.

Golang UTF8 RuneCountInString

func RuneCountInString(s string) (n int)

Golang UTF8 RuneCountInString function is like RuneCount but its input is a string.

Golang UTF8 Valid

func Valid(b []byte) bool

Golang UTF8 Valid function returns a boolean value true if the byte array consists entirely of valid UTF-8-encoded runes, else false.

func main() {
	valid := []byte("Hello, दुनिया") // World in Hindi
	invalid := []byte{0xff, 0xfe, 0xfd}

	fmt.Println(utf8.Valid(valid))
	fmt.Println(utf8.Valid(invalid))
}

Output:

true
false

ValidRune and ValidString work the same as the Valid function. The only difference is in the input section, the ValidRune take rune as input and the ValidString takes a string value as input.

Hope you like it!

Also, read Why Golang is called the future of Server-side language?

Learn more about Golang UTF8 Package from the official Documentation.

Понравилась статья? Поделить с друзьями:
  • Golang compile for linux on windows
  • Golang build for linux from windows
  • Gog скачать бесплатно для windows 10
  • Gog galaxy скачать на русском на windows 10
  • Gog galaxy не запускается на windows 10