@egorggegor

Из-за чего, когда я конвертирую байты в строку и обратно, то байты отличаются?

Есть следующий код:
func main() {
	bts := []byte("kek")
	btsToStr := fmt.Sprintf("%x", bts)
	fmt.Println(btsToStr)

	strToBts := []byte(btsToStr)
	fmt.Println(fmt.Sprintf("%x", strToBts))
}

Он выведет:
6b656b
366236353662

Почему так происходит? По идее должны быть одни и те же байты, но, кажется, sprintf как-то меняет данные.

В это же время следующий код:
func main() {
	bts := []byte("kek")
	btsToStr := string(bts)
	fmt.Println(btsToStr)

	strToBts := []byte(btsToStr)
	fmt.Println(string(strToBts))
}

Выведет:
kek
kek

Из-за чего так происходит?
Второй пример мне не подходит, потому что если подать ему странные символы, которые не читаются UTF8, то у меня в базу данные не попадут.
Подскажите пожалуйста, как можно нормально конвертить из байтов в строку и обратно?
  • Вопрос задан
  • 163 просмотра
Решения вопроса 1
В первом примере вы не конвертируете байты в строку и обратно. Вы конвертируете байты в их хекс-коды, а потом еще раз конвертируете результат в хекс-коды. Логично, что у вас не получается одинаковой строки, ибо вы два раза кодируете и ни одного раза не декодируете.
Если вам нужно положить какие-то бинарные данные во что-то, что поддерживает только ASCII-текст, используйте лучше base64.
https://go.dev/play/p/NPrAMrsHZje
package main

import (
	"encoding/base64"
	"fmt"
)

func main() {
	srcString := "Привет, тут есть юникод"
	fmt.Println("Исходный текст:", srcString)

	codedStr := base64.StdEncoding.EncodeToString([]byte(srcString))
	fmt.Println("После кодирования:", string(codedStr))

	resBytes, err := base64.StdEncoding.DecodeString(codedStr)
	if err != nil {
		fmt.Println("Ошибка декодирования:", err)
		return
	}
	resString := string(resBytes)
	fmt.Println("После декодирования обратно:", resString)
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Ничего удивительного.
В документации указано что делает %x в Sprintf.

Если нужно убедиться в корректности в строке, то использовать strings.ToValidUTF8.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы