Как определить кодировку текстового файла в windows

Программный комплекс SocialKit корректно работает с кириллицей в текстовых файлах, кодировка которых соответствует стандарту Windows-1251 (кратко может быть записано как CP1251 или ANSI). В этой связи в задачах, поддерживающих указание внешнего файла с перечнем комментариев, сообщений, описаний и прочей информации, которая может содержать кириллицу, нужно указывать текстовые файлы, где русский текст задан в кодировке по стандарту Windows-1251 или же просто ANSI, или CP1251 — всё это, по сути, одно и то же.

Учитывая, что многие инструменты по работе с текстом не отображают, в какой именно кодировке задан текст в текстовом файле и/или не поддерживают преобразование кодировок, то у новичков часто возникает вопрос о том, как именно привести кодировку текстового файла с русским текстом к понятному для SocialKit формату CP1251.

Следует сразу отметить, что большинство текстовых редакторов для ОС Windows (например, встроенный Блокнот и Wordpad) по умолчанию создают текстовые файлы именно с кодировкой по стандарту Windows-1251. Однако, эта кодировка по умолчанию может быть изменена в следствие тех или иных действий.

Если вы не уверены в том, в какой именно кодировке задан текст, то проще всего этот текст пересохранить через стандартный Блокнот Windows. При пересохранении Блокнот также покажет, в каком формате текст сейчас.

Опишем эту простую процедуру по шагам.

1. Открыть искомый текстовый файл в Блокноте Windows и выбрать пункт меню «Файл» -> «Сохранить как…».

Image 47453

Пример текстового файла, в котором русский текст задан в формате UTF, но это не очевидно при открытии.

2. В открывшемся диалоговом окне вы сразу видите, в какой кодировке был сохранён текст в текстовом файле.

Image 47454

Диалоговое окно пересохранения текстового файла, в котором можно сразу изменить кодировку.

Как видно, в примере текст в текстовом файле был ранее сохранён в кодировке UTF-8. Для изменения кодировке достаточно выбрать в выпадающем списке кодировку ANSI и нажать кнопку «Сохранить«.

При этом зрительно для вас ничего не изменится, но многое изменится для программы и алгоритмов, занимающихся обработкой текста в процессе отправки. Корректно Instagram’у будет отправлен только ANSI-текст.

This isn’t really a programming question, is there a command line or Windows tool (Windows 7) to get the current encoding of a text file? Sure I can write a little C# app but I wanted to know if there is something already built in?

Ross Ridge's user avatar

Ross Ridge

38.5k7 gold badges81 silver badges113 bronze badges

asked Sep 14, 2010 at 15:28

TheWebGuy's user avatar

3

Open up your file using regular old vanilla Notepad that comes with Windows 7.
It will show you the encoding of the file when you click «Save As…«.
It’ll look like this:
enter image description here

Whatever the default-selected encoding is, that is what your current encoding is for the file.

If it is UTF-8, you can change it to ANSI and click save to change the encoding (or visa-versa).

There are many different types of encodings, but this was all I needed when our export files were in UTF-8 and the 3rd party required ANSI. It was a onetime export, so Notepad fit the bill for me.

FYI: From my understanding I think «Unicode» (as listed in Notepad) is a misnomer for UTF-16.
More here on Notepad’s «Unicode» option: Windows 7 — UTF-8 and Unicode

Update (06/14/2023):

Updated with screenshots of the newer Notepad and Notepad++

Notepad (Windows 10 & 11):
   Bottom-Right Corner: enter image description here

   «Save As…» Dialog Box: enter image description here

Notepad++:
   Bottom-Right Corner: enter image description here

   «Encoding» Menu Item: enter image description here
   Far more Encoding options are available in NotePad++; should you need them.

Other (Mac/Linux/Win) Options:

I hear Windows 11 improved the performance of large 100+MB files to open much faster.
On the web I’ve read that Notepad++ is still the all around large-file editor champion.
However, (for those on Mac or Linux) here are some other contenders I found:
1). Sublime Text
2). Visual Studio Code

answered Nov 20, 2012 at 0:27

MikeTeeVee's user avatar

MikeTeeVeeMikeTeeVee

18.7k7 gold badges76 silver badges70 bronze badges

14

If you have «git» or «Cygwin» on your Windows Machine, then go to the folder where your file is present and execute the command:

file *

This will give you the encoding details of all the files in that folder.

answered Apr 19, 2017 at 7:37

George Ninan's user avatar

George NinanGeorge Ninan

2,0072 gold badges13 silver badges8 bronze badges

4

The (Linux) command-line tool ‘file’ is available on Windows via GnuWin32:

http://gnuwin32.sourceforge.net/packages/file.htm

If you have git installed, it’s located in C:\Program Files\git\usr\bin.

Example:

    C:\Users\SH\Downloads\SquareRoot>file *
    _UpgradeReport_Files;         directory
    Debug;                        directory
    duration.h;                   ASCII C++ program text, with CRLF line terminators
    ipch;                         directory
    main.cpp;                     ASCII C program text, with CRLF line terminators
    Precision.txt;                ASCII text, with CRLF line terminators
    Release;                      directory
    Speed.txt;                    ASCII text, with CRLF line terminators
    SquareRoot.sdf;               data
    SquareRoot.sln;               UTF-8 Unicode (with BOM) text, with CRLF line terminators
    SquareRoot.sln.docstates.suo; PCX ver. 2.5 image data
    SquareRoot.suo;               CDF V2 Document, corrupt: Cannot read summary info
    SquareRoot.vcproj;            XML  document text
    SquareRoot.vcxproj;           XML document text
    SquareRoot.vcxproj.filters;   XML document text
    SquareRoot.vcxproj.user;      XML document text
    squarerootmethods.h;          ASCII C program text, with CRLF line terminators
    UpgradeLog.XML;               XML  document text

    C:\Users\SH\Downloads\SquareRoot>file --mime-encoding *
    _UpgradeReport_Files;         binary
    Debug;                        binary
    duration.h;                   us-ascii
    ipch;                         binary
    main.cpp;                     us-ascii
    Precision.txt;                us-ascii
    Release;                      binary
    Speed.txt;                    us-ascii
    SquareRoot.sdf;               binary
    SquareRoot.sln;               utf-8
    SquareRoot.sln.docstates.suo; binary
    SquareRoot.suo;               CDF V2 Document, corrupt: Cannot read summary infobinary
    SquareRoot.vcproj;            us-ascii
    SquareRoot.vcxproj;           utf-8
    SquareRoot.vcxproj.filters;   utf-8
    SquareRoot.vcxproj.user;      utf-8
    squarerootmethods.h;          us-ascii
    UpgradeLog.XML;               us-ascii

Ed S.'s user avatar

Ed S.

123k22 gold badges185 silver badges265 bronze badges

answered Jan 13, 2016 at 11:58

Sybren's user avatar

SybrenSybren

8896 silver badges5 bronze badges

7

Install git ( on Windows you have to use git bash console). Type:

file --mime-encoding *   

for all files in the current directory , or

file --mime-encoding */*   

for the files in all subdirectories

Ross Rogers's user avatar

Ross Rogers

23.6k27 gold badges109 silver badges165 bronze badges

answered Nov 15, 2019 at 14:57

phd_coder's user avatar

phd_coderphd_coder

4194 silver badges3 bronze badges

2

Here’s my take how to detect the Unicode family of text encodings via BOM. The accuracy of this method is low, as this method only works on text files (specifically Unicode files), and defaults to ascii when no BOM is present (like most text editors, the default would be UTF8 if you want to match the HTTP/web ecosystem).

Update 2018: I no longer recommend this method. I recommend using file.exe from GIT or *nix tools as recommended by @Sybren, and I show how to do that via PowerShell in a later answer.

# from https://gist.github.com/zommarin/1480974
function Get-FileEncoding($Path) {
    $bytes = [byte[]](Get-Content $Path -Encoding byte -ReadCount 4 -TotalCount 4)

    if(!$bytes) { return 'utf8' }

    switch -regex ('{0:x2}{1:x2}{2:x2}{3:x2}' -f $bytes[0],$bytes[1],$bytes[2],$bytes[3]) {
        '^efbbbf'   { return 'utf8' }
        '^2b2f76'   { return 'utf7' }
        '^fffe'     { return 'unicode' }
        '^feff'     { return 'bigendianunicode' }
        '^0000feff' { return 'utf32' }
        default     { return 'ascii' }
    }
}

dir ~\Documents\WindowsPowershell -File | 
    select Name,@{Name='Encoding';Expression={Get-FileEncoding $_.FullName}} | 
    ft -AutoSize

Recommendation: This can work reasonably well if the dir, ls, or Get-ChildItem only checks known text files, and when you’re only looking for «bad encodings» from a known list of tools. (i.e. SQL Management Studio defaults to UTF16, which broke GIT auto-cr-lf for Windows, which was the default for many years.)

answered Jan 22, 2015 at 0:02

yzorg's user avatar

yzorgyzorg

4,2543 gold badges39 silver badges57 bronze badges

8

A simple solution might be opening the file in Firefox.

  1. Drag and drop the file into firefox
  2. Press Ctrl+I to open the page info

and the text encoding will appear on the «Page Info» window.

enter image description here

Note: If the file is not in txt format, just rename it to txt and try again.

P.S. For more info see this article.

answered Aug 8, 2019 at 17:37

Just Shadow's user avatar

Just ShadowJust Shadow

11k6 gold badges57 silver badges75 bronze badges

1

I wrote the #4 answer (at time of writing). But lately I have git installed on all my computers, so now I use @Sybren’s solution. Here is a new answer that makes that solution handy from powershell (without putting all of git/usr/bin in the PATH, which is too much clutter for me).

Add this to your profile.ps1:

$global:gitbin = 'C:\Program Files\Git\usr\bin'
Set-Alias file.exe $gitbin\file.exe

And used like: file.exe --mime-encoding *. You must include .exe in the command for PS alias to work.

But if you don’t customize your PowerShell profile.ps1 I suggest you start with mine: https://gist.github.com/yzorg/8215221/8e38fd722a3dfc526bbe4668d1f3b08eb7c08be0
and save it to ~\Documents\WindowsPowerShell. It’s safe to use on a computer without git, but will write warnings when git is not found.

The .exe in the command is also how I use C:\WINDOWS\system32\where.exe from powershell; and many other OS CLI commands that are «hidden by default» by powershell, *shrug*.

answered Oct 18, 2017 at 17:36

yzorg's user avatar

yzorgyzorg

4,2543 gold badges39 silver badges57 bronze badges

4

you can simply check that by opening your git bash on the file location then running the command file -i file_name

example

user filesData
$ file -i data.csv
data.csv: text/csv; charset=utf-8

answered Feb 23, 2022 at 14:04

DINA TAKLIT's user avatar

DINA TAKLITDINA TAKLIT

7,25410 gold badges70 silver badges77 bronze badges

Some C code here for reliable ascii, bom’s, and utf8 detection: https://unicodebook.readthedocs.io/guess_encoding.html

Only ASCII, UTF-8 and encodings using a BOM (UTF-7 with BOM, UTF-8 with BOM,
UTF-16, and UTF-32) have reliable algorithms to get the encoding of a document.
For all other encodings, you have to trust heuristics based on statistics.

EDIT:

A powershell version of a C# answer from: Effective way to find any file’s Encoding. Only works with signatures (boms).

# get-encoding.ps1
param([Parameter(ValueFromPipeline=$True)] $filename)    
begin {
  # set .net current directoy                                                                                                   
  [Environment]::CurrentDirectory = (pwd).path
}
process {
  $reader = [System.IO.StreamReader]::new($filename, 
    [System.Text.Encoding]::default,$true)
  $peek = $reader.Peek()
  $encoding = $reader.currentencoding
  $reader.close()
  [pscustomobject]@{Name=split-path $filename -leaf
                BodyName=$encoding.BodyName
                EncodingName=$encoding.EncodingName}
}


.\get-encoding chinese8.txt

Name         BodyName EncodingName
----         -------- ------------
chinese8.txt utf-8    Unicode (UTF-8)


get-childitem -file | .\get-encoding

answered Nov 8, 2018 at 17:43

js2010's user avatar

js2010js2010

23.3k6 gold badges65 silver badges67 bronze badges

1

Looking for a Node.js/npm solution? Try encoding-checker:

npm install -g encoding-checker

Usage

Usage: encoding-checker [-p pattern] [-i encoding] [-v]
 
Options:
  --help                 Show help                                     [boolean]
  --version              Show version number                           [boolean]
  --pattern, -p, -d                                               [default: "*"]
  --ignore-encoding, -i                                            [default: ""]
  --verbose, -v                                                 [default: false]

Examples

Get encoding of all files in current directory:

encoding-checker

Return encoding of all md files in current directory:

encoding-checker -p "*.md"

Get encoding of all files in current directory and its subfolders (will take quite some time for huge folders; seemingly unresponsive):

encoding-checker -p "**"

For more examples refer to the npm docu or the official repository.

answered Jan 27, 2021 at 21:22

ToJo's user avatar

ToJoToJo

1,3591 gold badge15 silver badges26 bronze badges

0

EncodingChecker

File Encoding Checker is a GUI tool that allows you to validate the text encoding of one or more files. The tool can display the encoding for all selected files, or only the files that do not have the encodings you specify.

File Encoding Checker requires .NET 4 or above to run.

answered Jul 8, 2020 at 16:29

Amr Ali's user avatar

Amr AliAmr Ali

3,0881 gold badge16 silver badges11 bronze badges

Similar to the solution listed above with Notepad, you can also open the file in Visual Studio, if you’re using that. In Visual Studio, you can select «File > Advanced Save Options…»

The «Encoding:» combo box will tell you specifically which encoding is currently being used for the file. It has a lot more text encodings listed in there than Notepad does, so it’s useful when dealing with various files from around the world and whatever else.

Just like Notepad, you can also change the encoding from the list of options there, and then saving the file after hitting «OK». You can also select the encoding you want through the «Save with Encoding…» option in the Save As dialog (by clicking the arrow next to the Save button).

answered Oct 11, 2016 at 18:57

JaykeBird's user avatar

JaykeBirdJaykeBird

3826 silver badges17 bronze badges

2

The only way that I have found to do this is VIM or Notepad++.

answered Sep 14, 2017 at 15:49

Todd Partridge's user avatar

Todd PartridgeTodd Partridge

6611 gold badge8 silver badges11 bronze badges

1

Кодировка — это способ представления символов текста в виде чисел, а также правила, по которым эти числа преобразуются в последовательности байтов для сохранения или передачи. Ошибочная интерпретация кодировки может привести к неправильному отображению символов и ошибкам при обработке данных. Поэтому важно знать, как узнать кодировку файла.

Определение кодировки файла может быть полезно во многих ситуациях. Например, если вы работаете с данными, полученными от другого пользователя или из внешнего источника, неизвестная кодировка может сделать эти данные непригодными для использования. Или же вы можете столкнуться с проблемами при отображении или обработке текста в различных программных средах. Поэтому знание способов определения кодировки файла является важным навыком для программистов, веб-разработчиков и тех, кто работает с текстовыми данными.

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

Содержание

  1. Как определить кодировку файла: два простых способа
  2. Просмотр файла в текстовом редакторе
  3. Использование специальных онлайн-сервисов
  4. Вопрос-ответ
  5. Какой самый простой способ определить кодировку файла?
  6. Можно ли определить кодировку файла с помощью текстового редактора?
  7. Как определить кодировку файла при помощи командной строки?
  8. Какими еще способами можно определить кодировку файла?
  9. Можно ли определить кодировку файла по его содержимому?
  10. Если ни один способ не помог определить кодировку файла, что делать?

Как определить кодировку файла: два простых способа

Определение кодировки файла может быть полезным, когда необходимо работать с текстовыми файлами, например, при обработке данных или при создании веб-страниц. Существует несколько способов определить кодировку файла, но в данной статье мы рассмотрим два простых метода.

  1. Анализ файловой сигнатуры

При открытии файла компьютер считывает несколько первых байт, которые называются файловой сигнатурой (или магическим числом). Эта последовательность байт содержит информацию о формате файла и его кодировке. С помощью анализа файловой сигнатуры можно приблизительно определить кодировку файла.

Например, если файл начинается с байтовой последовательности EF BB BF, то это означает, что файл закодирован в формате UTF-8 с BOM (Byte Order Mark). Если файл начинается с FF FE или FE FF, то это обычно указывает на кодировку UTF-16 или UTF-16BE.

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

  1. Использование утилиты file

Утилита file является стандартным инструментом в большинстве операционных систем, позволяющим определить тип и кодировку файла. Для использования утилиты file достаточно открыть командную строку (терминал) и ввести следующую команду:

file имя_файла

Команда file проанализирует содержимое файла и выведет информацию о его типе и кодировке. Например, если файл имеет кодировку UTF-8, то вывод команды file будет примерно следующим:

имя_файла: UTF-8 Unicode text

Использование утилиты file является наиболее надежным способом определения кодировки файла, поскольку она учитывает большое количество кодировок и может дать более точный результат, чем анализ файловой сигнатуры.

Теперь вы знаете два простых способа определить кодировку файла. Они могут быть полезны при работе с текстовыми данными и помогут вам выбрать правильную кодировку для дальнейшей обработки или отображения текста.

Просмотр файла в текстовом редакторе

Еще одним простым способом определить кодировку файла является просмотр его содержимого в текстовом редакторе. Делo в том, что разные кодировки отображают символы по-разному, и это позволяет нам сделать предположение о кодировке файла.

Вот несколько признаков, на которые можно обратить внимание при просмотре файла в текстовом редакторе:

  • Отображение специальных символов: некоторые кодировки могут отображать специальные символы, такие как кавычки, апострофы или тире, по-разному. Если вы видите странные символы вместо ожидаемых, это может быть признаком использования неправильной кодировки.
  • Размер файла: если кодировка файла отличается от предполагаемой, это может привести к увеличению размера файла. Это связано с тем, что некоторые кодировки используют больше байтов для представления символов. Если размер файла больше, чем вы ожидали, это может быть признаком неправильной кодировки.
  • Отображение русских символов: если файл содержит русский текст, вы можете обратить внимание на правильность отображения русских символов. Если они отображаются неправильно или в виде иероглифов, это может указывать на неправильную кодировку.

Однако, следует заметить, что просмотр файла в текстовом редакторе может дать лишь предположение о кодировке файла, но не гарантировать 100% точность. Для полной уверенности в кодировке следует использовать специализированные программы или методы.

Использование специальных онлайн-сервисов

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

Одним из таких сервисов является FileFormat.info. Для того чтобы воспользоваться этим сервисом, необходимо открыть его сайт и загрузить файл, кодировку которого нужно определить. После загрузки файла, сервис автоматически определит его кодировку и выведет информацию о ней на экране.

Еще одним популярным онлайн-сервисом является Encodist. Для использования этого сервиса необходимо загрузить файл на сайт и нажать кнопку «Определить кодировку». Сервис проанализирует загруженный файл и покажет его кодировку на экране.

Также стоит упомянуть о таком сервисе, как Online UTF-8 Tools. Он предоставляет возможность определить кодировку текстового файла и преобразовать его в другую кодировку. Для того чтобы воспользоваться данным сервисом, необходимо загрузить файл на сайт и выбрать нужные опции в поле «Conversion Options». После этого, сервис проанализирует файл и покажет его кодировку на экране.

Использование специальных онлайн-сервисов для определения кодировки файла является очень удобным способом, особенно для людей, которые не имеют достаточного опыта в работе с компьютером или не желают устанавливать дополнительное программное обеспечение. Все, что нужно сделать — это загрузить файл на сервис и получить результат.

Вопрос-ответ

Какой самый простой способ определить кодировку файла?

Самый простой способ определить кодировку файла — это использование онлайн-сервисов, которые автоматически определяют кодировку текста. Для этого достаточно загрузить файл на сайт или ввести текст в специальное поле, и сервис выполнит анализ и определит кодировку.

Можно ли определить кодировку файла с помощью текстового редактора?

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

Как определить кодировку файла при помощи командной строки?

Для определения кодировки файла через командную строку можно использовать утилиту `file` в Linux или Mac OS. Для этого нужно открыть терминал, перейти в папку с файлом и ввести команду `file -i имя_файла`. Утилита `file` выведет информацию о кодировке файла.

Какими еще способами можно определить кодировку файла?

Кроме онлайн-сервисов, текстовых редакторов и командной строки, существуют и другие способы определения кодировки файла. Например, можно использовать специальные программы для работы с текстом, такие как Notepad2 или Sublime Text. Также есть программы, которые могут провести анализ и определить кодировку файлов в пакетном режиме.

Можно ли определить кодировку файла по его содержимому?

Да, возможно определить кодировку файла по его содержимому. Кодировки имеют определенные характеристики, и анализируя эти характеристики, можно определить кодировку. Например, наличие определенных символов или последовательностей символов может указывать на определенную кодировку.

Если ни один способ не помог определить кодировку файла, что делать?

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

Автоопределение кодировки текста

Время на прочтение
6 мин

Количество просмотров 55K

image

Введение

Я очень люблю программировать, я любитель и первый и последний раз заработал на программировании в далёком 1996 году. Но для автоматизации повседневных задач иногда что-то пишу. Примерно год назад открыл для себя golang. В качестве инструмента создания утилит golang оказался очень удобным. Итак.

Возникла потребность обработать большое количество (больше тысячи, так и вижу улыбки профи) архивных файлов со специальной геофизической информацией. Формат файлов текстовый, простой. Если вдруг интересно то это LAS формат.
LAS файл содержит заголовок и данные.

Данные практически CSV, только разделитель табуляция или пробелы.

А заголовок содержит описание данных и вот в нём обычно содержится русский текст. Это может быть название месторождения, название исследований, записанных в файл и пр.

Файлы эти созданы в разное время и в разных программах, доходит до того, что в одном файле часть в кодировке CP1251, а часть в CP866. Файлы эти мне нужно обработать, а значит понять. Вот и потребовалось определять автоматически кодировку файла.

В итоге изобрёл велосипед на golang и соответственно родилась маленькая библиотечка с возможностью детектировать кодовую страницу.

Про кодировки. Не так давно на хабре была хорошая статья про кодировки Как работают кодировки текста. Откуда появляются «кракозябры». Принципы кодирования. Обобщение и детальный разбор Если хочется понять, что такое “кракозябры” или “кости”, то стоит прочитать.

В начале я накидал своё решение. Потом пытался найти готовое работающее решение на golang, но не вышло. Нашлось два решения, но оба не работают.

  • Первое “из коробки”— golang.org/x/net/html/charset функция DetermineEncoding()
  • Второе библиотека — saintfish/chardet на github

Обе уверенно ошибаются на некоторых кодировках. Стандартная та вообще почти ничего определить не может по текстовым файлам, оно и понятно, её для html страниц делали.

При поиске часто натыкался на готовые утилиты из мира linux — enca. Нашёл её версию скомпилированную для WIN32, версия 1.12. Её я тоже рассмотрю, там есть забавности. Я прошу сразу прощения за своё полное незнание linux, а значит возможно есть ещё решения которые тоже можно попытаться прикрутить к golang коду, я больше искать не стал.

Сравнение найденных решений на автоопределение кодировки

Подготовил каталог softlandia\cpd тестовые данные с файлами в разных кодировках. Содержимое файлов очень короткое и одинаковое. Одна строка “Русский в кодировке CodePageName”. Дополнил файлами со смешением кодировок и некоторыми сложными случаями и попробовал определить.

Мне кажется, получилось забавно.

Наблюдение 1

enca не определила кодировку у файла UTF-16LE без BOM — это странно, ну ладно. Я попробовал добавить больше текста, но результата не получил.

Наблюдение 2. Проблемы с кодировками CP1251 и KOI8-R

Строка 15 и 16. У команды enca есть проблемы.
Здесь сделаю объяснение, дело в том, что кодировки CP1251 (она же Windows 1251) и KOI8-R очень близки если рассматривать только алфавитные символы.

Таблица CP 1251

image

Таблица KOI8-r

image

В обеих кодировках алфавит расположен от 0xC0 до 0xFF, но там, где у одной кодировки заглавные буквы, у другой строчные. Судя по всему enca, работает по строчным буквам. Вот и получается, если подать на вход программе enca строку “СТП” в кодировке CP1251, то она решит, что это строка “яро” в кодировке KOI8-r, о чём и сообщит. В обратную сторону также работает.

Наблюдение 3

Стандартной библиотеке html/charset можно доверить только определение UTF-8, но осторожно! Пользоваться следует именно charset.DetermineEncoding(), поскольку метод utf8.Valid(b []byte) на файлах в кодировке utf-16be возвращает true.

Собственный велосипед

image

Автоопределение кодировки возможно только эвристическими методами, неточно. Если мы не знаем, на каком языке и в какой кодировке записан текстовый файл, то определить кодировку с высокой точночностью наверняка можно, но будет сложновато… и нужно будет достаточно много текста.

Для меня такая цель не стояла. Мне достаточно определять кодировки в предположении, что там есть русский язык. И второе, определять нужно по небольшому количеству символов – на 10 символах должно быть достаточно уверенное определение, а желательно вообще на 5–6 символах.

Алгоритм

Когда я обнаружил совпадение кодировок KOI8-r и CP1251 по местоположению алфавита, то на пару дней загрустил… стало понятно, что чуть-чуть придётся подумать. Получилось так.

Основные решения:

  1. Работу будем вести со слайсом байтов, для совместимости с charset.DetermineEncoding()
  2. Кодировку UTF-8 и случаи с BOM проверяем отдельно
  3. Входные данные передаём по очереди каждой кодировке. Каждая сама вычисляет два целочисленных критерия. У кого сумма двух критериев больше, тот и выиграл.

Критерии соответствия

Первый критерий

Первым критерием является количество самых популярных букв русского алфавита.

Наиболее часто встречаются буквы: о, е, а, и, н, т, с, р, в, л, к, м, д, п, у. Данные буквы дают 82% покрытия. Для всех кодировок кроме KOI8-r и CP1251 я использовал только первые 9 букв: о, е, а, и, н, т, с, р, в. Этого вполне хватает для уверенного определения.

А вот для KOI8-r и CP1251 пришлось доработать напильником. Коды некоторых из этих букв совпадают, например буква о имеет в CP1251 код 0xEE при этом в KOI8-r этот код у буквы н. Для этих кодировок были взяты следующие популярные буквы. Для CP1251 использовал а, и, н, с, р, в, л, к, я. Для KOI8-r — о, а, и, т, с, в, л, к, м.

Второй критерий

К сожалению, для очень коротких случаев (общая длина русского текста 5-6 символов) встречаемость популярных букв на уровне 1-3 шт и происходит нахлёст кодировок KOI8-r и CP1251. Пришлось вводить второй критерий. Подсчёт количества пар согласная+гласная.
Такие комбинации ожидаемо наиболее часто встречаются в русском языке и соответственно в той кодировке в которой число таких пар больше, та кодировка имеет больший критерий.

Вычисляются оба критерия, складываются и полученная сумма является итоговым критерием.
Результат отражен в таблице выше.

Особенности, с которыми я столкнулся

Чуть коснусь прелестей и проблем, связанных с golang. Раздел может быть интересен только начинающим писать на golang.

Проблемы

Лично походил по некоторым подводным камушкам из 50 оттенков Go: ловушки, подводные камни и распространённые ошибки новичков.
Излишне переживая и пытаясь дуть на воду, прослышав от других о страшных ожогах от молока, переборщил с проверкой входного параметра типа io.Reader. Я проверял переменную типа io.Reader с помощью рефлексии.

//CodePageDetect - detect code page of ascii data from reader 'r'
func CodePageDetect(r io.Reader, stopStr ...string) (IDCodePage, error) {
    if !reflect.ValueOf(r).IsValid() {
        return ASCII, fmt.Errorf("input reader is nil")
    }
...

Но как оказалось в моём случае достаточно проверить на nil. Теперь всё стало проще

func CodePageDetect(r io.Reader, stopStr ...string) (IDCodePage, error) {
    //test input interfase
    if r == nil {
        return ASCII, nil
    }
    //make slice of byte from input reader
    buf, err := bufio.NewReader(r).Peek(ReadBufSize)
    if (err != nil) && (err != io.EOF) {
        return ASCII, err
    }
...

вызов bufio.NewReader( r ).Peek(ReadBufSize) спокойно проходит следующий тест:

    var data *os.File
    res, err := CodePageDetect(data)

В этом случае Peek() возвращает ошибку.

Разок наступил на грабли с передачей массивов по значению. Немного тупанул на попытке изменять элементы, хранящиеся в map, пробегая по ним в range…

Прелести

Сложно сказать что конкретно, постоянное ли битьё по рукам от линтера и компилятора или активное использование range, или всё вместе, но практически отсутствуют залёты по выходу индекса за пределы.

Конечно, очень приятно жить со сборщиком мусора. Полагаю мне ещё предстоит освоить грабли автоматизации выделения/освобождения памяти, но пока дебильная улыбка не покидает лица.
Строгая типизация — тоже кусочек счастья.

Переменные, имеющие тип функции — соответственно лёгкая реализация различного поведения у однотипных объектов.

Странно мало пришлось сидеть в отладчике, перечитывание кода обычно даёт результат.

Щенячий восторг от наличия массы инструментов из коробки, это чудное ощущение, когда компилятор, язык, библиотека и IDE Visual Studio Code работают на тебя вместе, слаженно.

Спасибо falconandy за конструктивные и полезные советы
Благодаря ему

  1. перевёл тесты на testify и они действительно стали более читабельны
  2. исправил в тестах пути к файлам данных для совместимости с Linux
  3. прошёлся линтером — таки он нашёл одну реальную ошибку (проклятущий copy/past)

Продолжаю добавлять тесты, выявился случай не определения UTF16. Обновил. Теперь UTF16 и LE и BE определяются даже в случае отсутствия русских букв

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

Чтобы правильно прочесть файл нужно сначала посмотреть, есть ли в начале файла Маркер последовательности (тут точнее). Если есть маркер, его нужно определить. Если маркера нет, как выше уже было сказано, нужно искать другой алгоритм определения кодировки.

Я тут целиком и полностью полагаюсь на IsTextUnicode, если маркера нет:

BYTE *pBuf;
size_t szRead, szBOM; // к-во прочитанных в файле байт и к-во байт маркера
enum Unicode eUnicode;
LPTSTR pszText;
...
// определяю, есть ли в тексте маркер (ручная работа)
szBOM = IsUnicodeRaw(pBuf, szRead, &eUnicode);
// вызов библиотечной ф-ции IsTextUnicode после собственной проверки
if(eUnicode != utf_16LE && ((szRead - szBOM) % 2 || !IsTextUnicode(pBuf + szBOM, (int) (szRead - szBOM), NULL)))
{
BYTE *pb = new BYTE[(szRead - szBOM + 1) * sizeof(wchar_t)];
unsigned int nCP = (eUnicode == utf_8) ? CP_UTF8 : (eUnicode == utf_7) ? CP_UTF7 : CP_ACP;
if (!MultiByteToWideChar(nCP, (nCP == CP_ACP) ? MB_PRECOMPOSED : 0, (LPCSTR) (pBuf + szBOM), (int) (szRead - szBOM), (LPWSTR) pb, (int) (szRead - szBOM)))
{
// ошибка...
}
delete[] pBuf;
pszText = (LPTSTR) (pszBuf = pb)
}
else
pszText = (LPTSTR) (pszBuf + szBOM);

После того как выяснил наличие маркера в ф-ции IsUnicodeRaw, обращаюсь к IsTextUnicode без маркера. Работает с UTF-8, с UTF-7 нужно разбираться — там последние 2 бита маркера являются частью следующего за маркером символа. ANSI-текст так же нормально кодирует в двухбайтовый.

Wind’а предпочитает UTF-8 и UTF-16LE. Перед тем как записать текст, его нужно либо перекодировать в ANSI ф-цией WideCharToMultibyte, либо в начало файла записать маркер кодировки UTF-8 или UTF-16LE, чтобы потом также прочесть.

  • Как определить главный монитор windows 10
  • Как определить какую разрядность windows устанавливать
  • Как определить какая windows на флешке
  • Как определить кодек bluetooth windows 10
  • Как определить дату установки windows