UTF-8 и BOM в CSV: как отличить кодировку от невидимого префикса

Как проверить UTF-8 BOM, ошибку INVALID_CSV_UTF8 и уже испорченную кириллицу без обещания автоматической перекодировки.

Метка в начале ленты как образ BOM и кодировки файла

Когда вместо кириллицы видны нечитаемые символы или имя первой колонки неожиданно не совпадает с ожидаемым, проверьте две разные причины: кодировку байтов и префикс BOM. Добавить BOM недостаточно, чтобы превратить Windows-1251 в UTF-8; удалить его недостаточно, чтобы восстановить уже испорченный текст.

В Neraviko CSV → JSON принимает корректный UTF-8. Он умеет снять UTF-8 BOM в начале текста, но не содержит выбора исходной кодовой страницы и не выполняет автоматическую перекодировку произвольного файла.

Что именно означает BOM

UTF-8 BOM — последовательность байтов EF BB BF в самом начале потока. В UTF-8 это сигнатура; порядок байтов она не меняет. Некоторые потребители ожидают её, другие — нет. Unicode FAQ: UTF и BOM, проверено 05.10.2026; дата публикации страницы не указана.

Байты BOM нужно отличать от похожих видимых символов . Последние могут быть следствием неправильного декодирования и повторного сохранения. По одному снимку текста нельзя надёжно определить, какие байты лежат в исходном файле. Сохраните оригинал и уточните экспортную кодировку у отправителя.

Открытый в редакторе файл и вставленный в веб-форму текст — тоже разные этапы. К моменту вставки байты уже могли пройти декодирование в редакторе. Если оно было неверным, CSV-конвертер получает испорченные Unicode-символы, а не оригинальные байты старой кодировки.

Проверенный пример UTF-8 BOM

Синтетический файл состоит из BOM, заголовка name и значения Ёж. Его начало в шестнадцатеричном виде:

EF BB BF 6E 61 6D 65 0A D0 81 D0 B6

В CSV → JSON используйте header=true, delimiter=comma, pretty=false, trailing_newline=false. Ожидаемый результат:

[{"name":"Ёж"}]

Метаданные операции csv.to_json содержат bom_removed=true. Пример выполнен прямым локальным вызовом версии 1 с указанными байтами. Ключ объекта — ровно name, без начального U+FEFF.

Без BOM тот же корректный UTF-8 даёт такой же JSON, но bom_removed=false. Это проверено отдельно. Поддержка BOM не означает, что конвертер должен добавлять его в полученный JSON.

Что происходит с другой кодировкой

Синтетический вход name, LF, затем одиночный байт C6 не является корректным UTF-8. Прямой вызов операции возвращает INVALID_CSV_UTF8. Отказ не угадывает, какой символ хотел записать автор. В рабочем файле сначала нужно правильно декодировать исходную кодировку и сохранить UTF-8.

Воспользуйтесь функцией перекодировки существующего редактора или экспортёра. Укажите известную исходную кодировку и UTF-8 как целевую; затем сравните несколько характерных слов с оригиналом. Не переименовывайте файл и не ограничивайтесь добавлением трёх байтов: это не меняет кодировку остального содержимого.

После перекодировки проверьте разделитель и кавычки. Корректный UTF-8 может содержать неправильный CSV; эти проверки независимы. И наоборот, правильно расположенные запятые не подтверждают, что кириллица прочитана верно.

Если символы уже заменены

Сохранённые вопросительные знаки или replacement character не содержат информации о первоначальных буквах. Конвертер может успешно разобрать такую строку, потому что полученный текст синтаксически корректен. Успех означает успешный разбор нынешних символов, а не восстановление исходных.

Для ремонта нужна оригинальная выгрузка, резервная копия или достоверный источник значений. Не заменяйте «похожие» буквы вручную в идентификаторах и именах: визуально одинаковые символы могут иметь разные кодовые точки. Сверяйте конкретные ключи, а не только общий вид таблицы.

Приёмка после исправления

  1. Оригинальный файл сохранён, кодировка экспортёра известна.
  2. Несколько слов с кириллицей совпадают с источником.
  3. Имя первой колонки не содержит неожиданного префикса.
  4. JSON содержит ожидаемые Unicode-символы и число записей.
  5. Целевой импортёр проверен на том же маленьком наборе.
  6. BOM добавляется или удаляется по его контракту, а не автоматически для всех файлов.

Neraviko ограничивает запрос 262 144 байтами, поля — 65 536 байтами, ширину — 256 колонками. Парсер принимает до 5 000 записей вместе с заголовком. Обработка серверная; сырые входы и выходы по контракту операции не сохраняются и не логируются по умолчанию. Для проверки кириллицы используйте искусственные значения.