Що відрізняється між UTF-8 та UTF-8 без BOM ? Який краще?
Що відрізняється між UTF-8 та UTF-8 без BOM ? Який краще?
Відповіді:
BT UTF-8 - це послідовність байтів на початку текстового потоку ( 0xEF, 0xBB, 0xBF
), що дозволяє читачеві більш надійно відгадати файл як закодований в UTF-8.
Зазвичай, BOM використовується для сигналізації про витривалість кодування, але оскільки ендіансність не має значення для UTF-8, BOM не є необхідним.
Відповідно до стандарту Unicode , BOM для файлів UTF-8 не рекомендується :
2.6 Схеми кодування
... Використання BOM не потрібно і не рекомендується для UTF-8, але може зустрічатися в контекстах, коли дані UTF-8 перетворюються з інших форм кодування, які використовують BOM або де BOM використовується як підпис UTF-8 . Додаткову інформацію див. У підрозділі «Позначка порядку байтів» у Розділі 16.8 .
Інші чудові відповіді вже відповіли, що:
EF BB BF
Але, як додаткова інформація до цього, BOM для UTF-8 може бути хорошим способом "запаху", якщо рядок була закодована в UTF-8 ... Або це може бути законною рядком у будь-якому іншому кодуванні ...
Наприклад, дані [EF BB BF 41 42 43] можуть бути:
Тому, хоча можна розпізнати кодування вмісту файлу, переглянувши перші байти, не можна покладатися на це, як показує приклад вище
Кодування повинні бути відомими, а не дозволеними.
Принаймні три проблеми із введенням BOM у файли, кодовані UTF-8.
І, як уже згадували інші, не достатньо і не потрібно мати BOM, щоб виявити, що щось є UTF-8:
cat
не дасть тобі чистого результату, результат, який має BOM лише на старті. Якщо ви це мали на увазі, то це тому, що cat
працює на рівні байтів, а не на рівні інтерпретованого вмісту, і подібним чином cat
не можу мати справу з фотографіями. Але це не приносить великої шкоди. Це тому, що BOM кодує нерозривний простір нульової ширини.
Ось приклади використання BOM, які насправді викликають реальні проблеми, але багато людей про це не знають.
Сценарії оболонки, скрипти Perl, сценарії Python, скрипти Ruby, скрипти Node.js або будь-який інший виконуваний файл, який повинен запускати інтерпретатор - все починається з рядка shebang, який виглядає як один із таких:
#!/bin/sh
#!/usr/bin/python
#!/usr/local/bin/perl
#!/usr/bin/env node
Він повідомляє системі, якого інтерпретатора потрібно запустити, коли викликає такий сценарій. Якщо сценарій кодується в UTF-8, можливо, спокуса включити BOM на початку. Але насправді "#!" символи - це не просто символи. Насправді вони є магічним числом , яке складається з двох символів ASCII. Якщо ви поставите щось (наприклад, BOM) перед цими символами, то файл виглядатиме так, що він мав інше магічне число, і це може призвести до проблем.
Дивіться Вікіпедію, статтю: Shebang, розділ: Чарівне число :
Символи shebang представлені тими ж двома байтами в розширених кодуваннях ASCII, включаючи UTF-8, який зазвичай використовується для сценаріїв та інших текстових файлів у поточних системах, схожих на Unix. Однак файли UTF-8 можуть починатися з необов'язкової позначки порядку байти (BOM); якщо функція "exec" спеціально виявляє байти 0x23 та 0x21, то наявність BOM (0xEF 0xBB 0xBF) перед шебангом не дозволить виконувати інтерпретатор сценарію.Деякі органи влади рекомендують забороняти використовувати позначку порядку байтів у сценаріях POSIX (подібних Unix) [14] з цієї причини та для ширшої інтероперабельності та філософських проблем. Додатково, марка порядку байтів не є необхідною в UTF-8, оскільки кодування не має проблем із витримкою; він служить лише для ідентифікації кодування як UTF-8. [наголос додано]
Див. RFC 7159, Розділ 8.1 :
Реалізації НЕ МОЖЕ додавати позначку порядку байтів на початок тексту JSON.
Він не тільки є незаконним у JSON, він також не потрібен для визначення кодування символів, оскільки існують більш надійні способи однозначного визначення кодування символів та ендіанності, що використовуються в будь-якому потоці JSON ( детальну інформацію див. У цій відповіді ).
Він не тільки незаконний у JSON і не потрібен , він фактично порушує все програмне забезпечення, яке визначає кодування, використовуючи метод, представлений в RFC 4627 :
Визначення кодування та витривалості JSON, вивчення перших чотирьох байт байта NUL:
00 00 00 xx - UTF-32BE
00 xx 00 xx - UTF-16BE
xx 00 00 00 - UTF-32LE
xx 00 xx 00 - UTF-16LE
xx xx xx xx - UTF-8
Тепер, якщо файл починається з BOM, він буде виглядати приблизно так:
00 00 FE FF - UTF-32BE
FE FF 00 xx - UTF-16BE
FF FE 00 00 - UTF-32LE
FF FE xx 00 - UTF-16LE
EF BB BF xx - UTF-8
Зауважте, що:
Залежно від реалізації, все це може трактуватися неправильно як UTF-8, а потім неправильно трактуватися або відкидатися як недійсне UTF-8 або взагалі не визнаватися.
Крім того, якщо тести реалізації для дійсного JSON, як я рекомендую, він відхилить навіть вхід, який дійсно закодований як UTF-8, оскільки він не починається з символу ASCII <128, як слід згідно з RFC.
BOM в JSON не потрібен, є незаконним і порушує програмне забезпечення, яке працює правильно відповідно до RFC. Це повинен бути нобілайзер, щоб просто не використовувати його тоді, і все ж, завжди є люди, які наполягають на порушенні JSON за допомогою BOMs, коментарів, різних правил цитування або різних типів даних. Звичайно, кожен може вільно користуватися такими речами, як BOM або що-небудь інше, якщо вам це потрібно - просто не називайте це JSON тоді.
Для інших форматів даних, ніж JSON, подивіться, як це насправді виглядає. Якщо єдиними кодуваннями є UTF- *, а перший символ повинен бути символом ASCII нижче 128, то у вас вже є вся інформація, необхідна для визначення як кодування, так і цілеспрямованості ваших даних. Додавання BOMs навіть як додаткова функція лише ускладнить його і схильний до помилок.
Щодо використання поза JSON або сценаріїв, я думаю, тут вже є дуже хороші відповіді. Я хотів додати більш детальну інформацію, зокрема про сценарії та серіалізацію, тому що це приклад символів BOM, що викликають реальні проблеми.
Що відрізняється між UTF-8 та UTF-8 без BOM?
Коротка відповідь: У UTF-8 BOM кодується як байти EF BB BF
на початку файлу.
Довга відповідь:
Спочатку очікувалося, що Unicode буде закодований в UTF-16 / UCS-2. BOM був розроблений для цієї форми кодування. Коли у вас є 2-байтні одиниці коду, необхідно вказати, в якому порядку вони знаходяться ці два байти, і загальним умовою для цього є включення символу U + FEFF як "Марка порядку байтів" на початку даних. Символ U + FFFE назавжди не призначений, щоб його наявність могла використовуватися для виявлення неправильного порядку байтів.
UTF-8 має той самий порядок байтів незалежно від витривалості платформи, тому позначка порядку байтів не потрібна. Однак може траплятися (як послідовність байтів EF BB FF
) у даних, які були перетворені в UTF-8 з UTF-16, або як "підпис", щоб вказати, що дані є UTF-8.
Який краще?
Без. Як відповів Мартін Кот, стандарт Unicode не рекомендує цього. Це спричиняє проблеми із програмним забезпеченням, яке не знає BOM.
Кращим способом виявити, чи є файл UTF-8, є перевірка дійсності. UTF-8 має суворі правила щодо того, які послідовності байтів є дійсними, тому ймовірність помилкового додатника незначна. Якщо послідовність байтів схожа на UTF-8, це, мабуть, так.
sh
, perl
, g++
і багатьом іншим безкоштовним і потужних інструментів. Хочете, щоб справи працювали? Просто придбайте версії MS. MS створили специфічну для платформи проблему так само, як і катастрофа їх діапазону \ x80- \ x95.
UTF-8 з BOM краще ідентифікувати. Я дійшов цього висновку важким шляхом. Я працюю над проектом, де одним із результатів є файл CSV , включаючи символи Unicode.
Якщо файл CSV зберігається без BOM, Excel вважає, що це ANSI, і показує хитрість. Після додавання "EF BB BF" спереду (наприклад, повторне збереження за допомогою блокнота з UTF-8; або блокнота ++ з UTF-8 з BOM) Excel відкриває його нормально.
Попередження символу BOM до текстових файлів Unicode рекомендується RFC 3629: "UTF-8, формат перетворення ISO 10646", листопад 2003 року на http://tools.ietf.org/html/rfc3629 (остання інформація знайдена за адресою: http://www.herongyang.com/Unicode/Notepad-Byte-Order-Mark-BOM-FEFF-EFBBBF.html )
BOM схиляється до бурхливості (не каламбур призначений (sic)) десь, десь. А коли він буває (наприклад, не розпізнається браузерами, редакторами тощо), він відображається як дивні символи 
на початку документа (наприклад, HTML-файл, відповідь JSON , RSS тощо). і спричиняє такі збентеження, як нещодавнє питання кодування, що виник під час розмови Обами у Twitter .
Це дуже дратує, коли воно з’являється в місцях, де важко налагодити або коли тестування нехтується. Тож краще уникати цього, якщо ви не повинні його використовувати.
Питання: Що відрізняється між UTF-8 та UTF-8 без BOM? Який краще?
Ось кілька уривків із статті Вікіпедії про позначення порядку байтів (BOM), які, на мою думку, пропонують ґрунтовну відповідь на це питання.
Про значення BOM та UTF-8:
Стандарт Unicode дозволяє BOM в UTF-8 , але не вимагає і не рекомендує його використовувати. Порядок байтів не має значення в UTF-8, тому його єдине використання в UTF-8 - це сигналізувати на початку, що текстовий потік закодований в UTF-8.
Аргумент за те, що НЕ використовувати BOM:
Основна мотивація невикористання BOM - це зворотна сумісність із програмним забезпеченням, яке не обізнане з Unicode ... Ще одна мотивація невикористання BOM - це заохочення UTF-8 як кодування "за замовчуванням".
Аргумент ЗА використання BOM:
Аргумент для використання BOM полягає в тому, що без цього необхідний евристичний аналіз, щоб визначити, який символ кодує файл. Історично такий аналіз, щоб виділити різні 8-бітові кодування, є складним, схильним до помилок, а іноді і повільним. Для полегшення завдання доступна низка бібліотек, такі як Mozilla Universal Charset Detector та International Components for Unicode.
Програмісти помилково припускають, що виявити UTF-8 однаково важко (це не тому, що переважна більшість послідовностей байтів є недійсними UTF-8, тоді як кодування, які ці бібліотеки намагаються розрізнити, дозволяють усі можливі послідовності байтів). Тому не всі програми, що знають Unicode, проводять такий аналіз і замість цього покладаються на BOM.
Зокрема, компілятори та інтерпретатори Microsoft , а також багато програмного забезпечення в Microsoft Windows, таких як Блокнот, не будуть правильно читати текст UTF-8, якщо він не містить лише символів ASCII або він починається з BOM, і додасть BOM до початку при збереженні текст як UTF-8. Документи Google додадуть BOM, коли документ Microsoft Word завантажується у вигляді простого текстового файлу.
Що краще, З або БЕЗ :
IETF рекомендує , якщо протокол або (а) завжди використовує UTF-8, або (б) має якийсь - то інший спосіб , щоб вказати , що використовується кодування, то «слід заборонити використання U + FEFF в якості підпису.»
Мій висновок:
Використовуйте BOM лише в тому випадку, якщо сумісність із програмним додатком абсолютно необхідна.
Також зауважте, що хоча посилання на статтю Wikipedia вказує на те, що багато програм Microsoft покладаються на BOM для правильного виявлення UTF-8, це не стосується всіх програм Microsoft. Наприклад, як вказував @barlop , при використанні командного рядка Windows з UTF-8 † команди такі, type
і more
не очікуйте, що BOM буде присутній. Якщо специфікація знаходиться присутній, вона може бути проблематичною, так і для інших застосувань.
† chcp
Команда пропонує підтримку UTF-8 ( без BOM) через кодову сторінку 65001 .
.htaccess
і gzip compression
в поєднанні з UTF-8 BOM видає помилку кодування Змінити для кодування в UTF-8 без BOM слідують до пропозиції , як пояснено тут вирішують проблеми
На це запитання вже є мільйон і один відповіді, і багато з них є досить хорошими, але я хотів спробувати уточнити, коли БОМ повинен чи не повинен використовуватися.
Як уже згадувалося, будь-яке використання UTF BOM (Byte Order Mark) для визначення того, чи є рядок UTF-8 чи ні, не є освіченою здогадкою. Якщо є відповідні метадані (наприклад charset="utf-8"
), ви вже знаєте, що ви повинні використовувати, але в іншому випадку вам потрібно перевірити і зробити деякі припущення. Це включає перевірку, чи починається файл з рядка, починаючи з шістнадцяткового байтового коду, EF BB BF.
Якщо знайдений байт-код, відповідний BOM UTF-8, ймовірність достатньо висока, щоб припустити, що це UTF-8, і ви можете піти звідти. Однак, коли змушені зробити це здогадка, додаткова перевірка помилок під час читання все-таки буде хорошою ідеєю, якщо щось зіпсується. Ви повинні припустити, що BOM не є UTF-8 (тобто латинська-1 або ANSI), якщо вхід точно не повинен бути UTF-8 на основі його джерела. Якщо BOM відсутній, ви можете просто визначити, чи повинен це бути UTF-8, перевіривши кодування.
Якщо ви не можете записати метадані будь-яким іншим способом (через тег шаблону або мета файлової системи), а програми, які використовуються як BOM, слід кодувати BOM. Особливо це стосується Windows, де звичайно вважається, що все, що не має BOM, використовує застарілу кодову сторінку. BOM повідомляє таким програмам, як Office, що так, текст у цьому файлі є Unicode; ось використано кодування.
Коли справа доходить до цього, єдині файли, з якими у мене колись виникають проблеми - це CSV. Залежно від програми, вона або повинна, або не повинна мати BOM. Наприклад, якщо ви використовуєте Excel 2007+ у Windows, він повинен бути закодований BOM, якщо ви хочете його відкрити плавно і не потрібно вдаватися до імпорту даних.
Слід зазначити, що для деяких файлів ви не повинні мати BOM навіть у Windows. Прикладами є SQL*plus
або VBScript
файли. Якщо такі файли містять BOM, ви отримуєте помилку при спробі їх виконання.
UTF-8 з BOM допомагає лише в тому випадку, якщо файл насправді містить деякі символи, що не належать до ASCII. Якщо він включений, а таких немає, то, можливо, він може зламати старіші програми, які б інакше інтерпретували файл як звичайний ASCII. Ці програми, безумовно, не вдасться, коли вони натрапляють на не ASCII-символ, тому, на мій погляд, BOM слід додавати лише тоді, коли файл може і не повинен більше інтерпретуватися як звичайний ASCII.
Я хочу дати зрозуміти, що я волію взагалі не мати BOM. Додайте його, якщо якийсь старий сміття перерветься без нього, а заміна цього застарілого додатка неможлива.
Не варто сподіватися на те, що BOM для UTF-8.
Цитується внизу сторінки Вікіпедії на BOM: http://en.wikipedia.org/wiki/Byte-order_mark#cite_note-2
"Використання BOM не потрібно і не рекомендується для UTF-8, але може зустрічатися в контекстах, коли дані UTF-8 перетворюються з інших форм кодування, які використовують BOM або де BOM використовується як підпис UTF-8"
UTF-8 без BOM не має BOM, що не робить його кращим, ніж UTF-8 з BOM, за винятком випадків, коли споживачеві файлу потрібно знати (або виграє від того, щоб знати), чи файл у кодованому UTF-8 чи ні.
BOM зазвичай корисний для визначення витривалості кодування, що не потрібно для більшості випадків використання.
Крім того, BOM може бути непотрібним шумом / болем для тих споживачів, які не знають і не піклуються про це, і може призвести до плутанини користувачів.
Я дивлюся на це з іншого погляду. Я думаю, що UTF-8 з BOM є кращим, оскільки він надає більше інформації про файл. Я використовую UTF-8 без BOM, тільки якщо зіткнувся з проблемами.
Я довго використовую кілька мов (навіть кирилицю ) на своїх сторінках, і коли файли зберігаються без BOM, і я повторно відкриваю їх для редагування за допомогою редактора (як також зазначав cherouvim ), деякі символи пошкоджуються.
Зауважте, що класичний блокнот Windows автоматично зберігає файли з BOM при спробі збереження новоствореного файлу з кодуванням UTF-8.
Я особисто зберігаю файли сценаріїв на стороні сервера (.asp, .ini, .aspx) з BOM та .html файлами без BOM .
chcp 65001
для підтримки utf8, це utf8 без bom. Якщо ви type myfile
це зробите, він відображатиметься належним чином, лише якщо бомби немає. Якщо ви зробите echo aaa>a.a
або echo אאא>a.a
виведете символи для файлу aa, і у вас є chcp 65001, він виведе без BOM.
Коли ви хочете відобразити інформацію, закодовану в UTF-8, у вас можуть не виникнути проблеми. Задекларуйте, наприклад, документ HTML як UTF-8, і у вашому браузері буде все, що міститься в тілі документа.
Але це не так, коли ми маємо текстові, CSV та XML-файли або в Windows, або в Linux.
Наприклад, текстовий файл в Windows або Linux - одна з найпростіших речей, яку можна уявити, це (зазвичай) UTF-8.
Збережіть його як XML і оголосіть його як UTF-8:
<?xml version="1.0" encoding="UTF-8"?>
Він не відобразиться правильно (його не буде прочитано) правильно, навіть якщо він оголошений як UTF-8.
У мене був ряд даних, що містять французькі літери, які потрібно було зберегти як XML для синдикації. Без створення файлу UTF-8 з самого початку (зміни параметрів в IDE та "Створення нового файлу") або додавання BOM на початку файлу
$file="\xEF\xBB\xBF".$string;
Мені не вдалося зберегти французькі літери у файлі XML.
Одна практична відмінність полягає в тому, що якщо ви напишете сценарій оболонки для Mac OS X і збережете його як звичайний UTF-8, ви отримаєте відповідь:
#!/bin/bash: No such file or directory
у відповідь на рядок shebang, вказуючи, яку оболонку ви бажаєте використовувати:
#!/bin/bash
Якщо ви збережете як UTF-8, без BOM (скажімо в BBEdit ) все буде добре.
Як було сказано вище, UTF-8 з BOM може спричинити проблеми з програмним забезпеченням, яке не знає BOM (або сумісного). Я колись редагував HTML-файли, закодовані як UTF-8 + BOM, на базі Mozilla KompoZer , як клієнт вимагав, щоб програма WYSIWYG .
Незмінно макет може бути знищений при збереженні. Минуло певний час, щоб вирішити свій шлях. Потім ці файли добре працювали у Firefox, але знову показали CSS-химерність в Internet Explorer, що зруйнував макет. Після годинника, що поспілкувався із пов'язаними CSS-файлами, я виявив, що Internet Explorer не любить файл BOMfed HTML. Ніколи знову.
Також я щойно знайшов це у Вікіпедії:
Символи shebang представлені тими ж двома байтами в розширених кодуваннях ASCII, включаючи UTF-8, який зазвичай використовується для сценаріїв та інших текстових файлів у поточних системах, схожих на Unix. Однак файли UTF-8 можуть починатися з необов'язкової позначки порядку байти (BOM); якщо функція "exec" спеціально виявляє байти 0x23 0x21, то наявність BOM (0xEF 0xBB 0xBF) перед шебангом запобіжить виконанню інтерпретатора сценарію. Деякі органи влади рекомендують не використовувати позначку порядку байтів у сценаріях POSIX (схожий на Unix) [15] з цієї причини та для ширшої взаємодії та філософських проблем
Поширені запитання про марку порядку замовлення Unicode (BOM) містять стисну відповідь:
Питання: Як я маю поводитися з ВОМ?
Відповідь: Ось декілька вказівок, яких слід дотримуватися:
Конкретний протокол (наприклад, конвенції Microsoft для файлів .txt) може вимагати використання BOM у певних потоках даних Unicode, таких як файли. Коли вам потрібно відповідати такому протоколу, використовуйте BOM.
У деяких протоколах можливі необов'язкові BOM-файли у випадку без тегів тексту. У цих випадках
Якщо текстовий потік даних, як відомо, є звичайним текстом, але невідомого кодування, BOM може використовуватися як підпис. Якщо немає BOM, кодуванням може бути що завгодно.
Якщо текстовий потік даних, як відомо, являє собою звичайний текст Unicode (але не той, який є ендіан), то BOM може використовуватися як підпис. Якщо немає BOM, текст слід інтерпретувати як big-endian.
Деякі протоколи, орієнтовані на байт, очікують символів ASCII на початку файлу. Якщо UTF-8 використовується з цими протоколами, слід уникати використання BOM як підпису форми кодування.
Там, де відомий точний тип потоку даних (наприклад, Unicode big-endian або Unicode little-endian), BOM не слід використовувати. Зокрема, щоразу, коли потік даних оголошується UTF-16BE, UTF-16LE, UTF-32BE або UTF-32LE, BOM не повинен використовуватися.
З http://en.wikipedia.org/wiki/Byte-order_mark :
Марка порядку байтів (BOM) - символ Unicode, який використовується для сигналізації про ендіанси (порядок байтів) текстового файлу або потоку. Його кодова точка - U + FEFF. Використання BOM не є обов'язковим, і, якщо воно використовується, воно повинно з’являтися на початку текстового потоку. Крім конкретного використання в якості індикатора порядку байтів, символ BOM також може вказувати, в якому з декількох представлень Unicode текст закодований.
Завжди використання BOM у вашому файлі гарантує, що він завжди правильно відкривається в редакторі, який підтримує UTF-8 та BOM.
Моя реальна проблема з відсутністю BOM полягає в наступному. Припустимо, у нас є файл, який містить:
abc
Без BOM це відкривається як ANSI у більшості редакторів. Отож інший користувач цього файлу відкриває його та додає деякі рідні символи, наприклад:
abg-αβγ
На жаль, тепер файл все ще знаходиться в ANSI і вгадайте, що "αβγ" не займає 6 байтів, але 3. Це не UTF-8, і це спричиняє інші проблеми згодом у ланцюжку розробки.
Ось мій досвід запитів на витягування Visual Studio, Sourcetree та Bitbucket , що спричиняє мені деякі проблеми:
Так виходить, що BOM з підписом буде містити символ червоної крапки у кожному файлі при перегляді запиту на витягнення (це може бути дуже прикро).
Якщо ви наведіть на нього курсор, він покаже такий персонаж, як "ufeff", але, виявляється, Sourcetree не відображає ці типи побічних знаків, тож, швидше за все, це виявиться у ваших запитах на виклик, що має бути нормальним, оскільки саме так Visual Studio 2017 кодує нові файли зараз, тому, можливо, Bitbucket повинен ігнорувати це або змусити його показувати іншим способом, більше інформації тут:
UTF з BOM краще, якщо ви використовуєте UTF-8 у файлах HTML і якщо ви використовуєте сербську кирилицю, сербську латинську, німецьку, угорську або якусь екзотичну мову на одній сторінці.
Це моя думка (30 років обчислювальної та ІТ-індустрії).