Разделитель — это последовательность из одного или нескольких символов для указания границы между отдельными независимыми областями в виде обычного текста , математических выражений или других потоков данных . [1] [2] Примером разделителя является символ запятой , который действует как разделитель полей в последовательности значений, разделенных запятыми . Другим примером разделителя является временной интервал, используемый для разделения букв и слов при передаче кода Морзе .
В математике разделители часто используются для указания области действия и могут встречаться как в виде изолированных символов (например, двоеточие в « »), так и в виде пары противоположных символов (например, угловые скобки в ).
Разделители представляют собой один из различных способов указания границ в потоке данных . Например, декларативная нотация — это альтернативный метод, который использует поле длины в начале потока данных для указания количества символов, содержащихся в потоке данных. [3]
Разделители могут характеризоваться как разделители полей и записей или как разделители скобок.
Разделители полей разделяют поля данных. Разделители записей разделяют группы полей. [4]
Например, в формате CSV в качестве разделителя между полями используется запятая , а в качестве разделителя между записями — индикатор конца строки :
имя, имя, возраст, зарплатаНэнси, Даволио, 33 года, 30 000 долларовЭрин, Боракова, 28 лет, $25250Тони, Рафаэль, 35 лет, 28700 долларов
Это определяет простую таблицу базы данных с плоским файлом , использующую формат файла CSV.
Разделители в скобках, также называемые разделителями блоков, разделителями регионов или сбалансированными разделителями, отмечают начало и конец области текста. [5] [6]
Общие примеры разделителей скобок включают: [7]
Исторически сложилось так, что компьютерные платформы по соглашению использовали определенные разделители. [15] [16] В следующих таблицах приведены несколько примеров для сравнения.
Языки программирования ( См. также , Сравнение языков программирования (синтаксис) ).
Разделители полей и записей ( см . также ASCII , Управляющий символ ).
Столкновение разделителей — это проблема, которая возникает, когда автор или программист вводит разделители в текст, фактически не намереваясь интерпретировать их как границы между отдельными областями. [4] [18] Например, в случае XML это может произойти всякий раз, когда автор пытается указать символ угловой скобки .
В большинстве типов файлов есть как разделитель полей, так и разделитель записей, оба из которых могут конфликтовать. Например, в случае файлов со значениями, разделенными запятыми , конфликт полей может произойти всякий раз, когда автор пытается включить запятую как часть значения поля (например, зарплата = «30 000 долларов США»), а конфликт разделителей записей может произойти всякий раз, когда поле содержал несколько строк. В текстовых файлах часто возникают конфликты между записями и разделителями полей.
В некоторых случаях злоумышленник или злоумышленник может намеренно попытаться воспользоваться этой проблемой. Следовательно, конфликт разделителей может стать источником уязвимостей и эксплойтов безопасности . Злоумышленники могут воспользоваться конфликтом разделителей в таких языках, как SQL и HTML, для развертывания таких известных атак, как SQL-инъекция и межсайтовый скриптинг соответственно.
Поскольку столкновение разделителей является очень распространенной проблемой, были изобретены различные методы ее решения. Некоторые авторы могут попытаться избежать этой проблемы, выбрав символ-разделитель (или последовательность символов), который вряд ли появится в самом потоке данных. Этот специальный подход может быть подходящим, но он обязательно зависит от правильного предположения о том, что появится в потоке данных, и не обеспечивает защиты от злонамеренных коллизий. Поэтому применяются и другие, более формальные соглашения.
Наборы символов ASCII и Unicode были разработаны для решения этой проблемы путем предоставления непечатаемых символов, которые можно использовать в качестве разделителей. Это диапазон от ASCII 28 до 31.
Использование разделителя единиц ASCII 31 в качестве разделителя полей и разделителя записей ASCII 30 решает проблему разделителей как полей, так и записей, которые появляются в потоке текстовых данных. [19]
Одним из способов избежать столкновения разделителей является использование escape-символов . С точки зрения языкового дизайна они адекватны, но у них есть недостатки:
Escape-последовательности аналогичны escape-символам, за исключением того, что они обычно состоят из какой-то мнемоники, а не из одного символа. Одно из применений — строковые литералы , включающие символ двойной кавычки («»). Например, в Perl код:
print "Нэнси сказала \x22Hello World!\x22 толпе." ; ### используйте \x22
выдает тот же результат, что и:
print «Нэнси сказала толпе: «Привет, мир!»». ; ### используйте escape-символ
Одним из недостатков escape-последовательностей, когда они используются людьми, является необходимость запоминать коды, представляющие отдельные символы (см. также: ссылка на символьную сущность , ссылка на числовой символ ).
В отличие от escape-последовательностей и escape-символов, двойные разделители предоставляют еще один способ избежать столкновения разделителей. Некоторые языки, например, позволяют использовать одинарную кавычку (') или двойную кавычку ("") для указания строкового литерала. Например, в Perl :
print 'Нэнси сказала: «Привет, мир!» толпе». ;
производит желаемый результат, не требуя экранирования. Однако этот подход работает только в том случае, если строка не содержит оба типа кавычек.
В отличие от escape-последовательностей и escape-символов, заполняющие разделители предоставляют еще один способ избежать столкновения разделителей. Visual Basic , например, использует двойные кавычки в качестве разделителей. Это похоже на экранирование разделителя.
print «Нэнси сказала толпе «Привет, мир!»».
производит желаемый результат, не требуя экранирования. Однако, как и при обычном экранировании, использование большого количества кавычек может привести к путанице. Код для печати приведенного выше исходного кода выглядел бы более запутанным:
print "print ""Нэнси сказала """"Привет, мир!"""" толпе."""
В отличие от двойных разделителей, множественные разделители еще более гибки и позволяют избежать коллизий разделителей. [7] : 63
Например, в Perl :
print qq^Нэнси не хочет говорить «Привет, мир!» больше.^ ; print qq@Нэнси не хочет говорить «Привет, мир!» больше.@ ; print qq(Нэнси больше не хочет говорить «Hello World!».) ;
все они производят желаемый результат за счет использования операторов кавычек, которые позволяют любому удобному символу выступать в качестве разделителя. Хотя этот метод более гибок, его поддерживают немногие языки. Perl и Ruby — это два, которые это делают. [7] : 62 [21]
Граница содержимого — это особый тип разделителя, специально разработанный для предотвращения коллизий разделителей. Он работает, позволяя автору указать последовательность символов, которая гарантированно всегда указывает границу между частями в сообщении, состоящем из нескольких частей, без какой-либо другой возможной интерпретации. [22]
Разделитель часто генерируется из случайной последовательности символов, появление которой в контенте статистически маловероятно. За ним может следовать идентификационный знак, такой как UUID , временная метка или какой-либо другой отличительный знак. Альтернативно, содержимое можно сканировать, чтобы гарантировать, что разделитель не появится в тексте. Это может позволить сделать разделитель короче или проще, а также повысить удобочитаемость документа. ( См., например , MIME , здесь документы ).
Некоторые языки программирования и программирования позволяют использовать пробельные разделители или отступы как средство указания границ между независимыми областями в тексте. [23]
При указании регулярного выражения также можно использовать альтернативные разделители для упрощения синтаксиса операций сопоставления и замены в Perl . [24]
Например, в Perl можно указать простую операцию сопоставления со следующим синтаксисом:
$string1 = 'Нэнси сказала: «Привет, мир!» толпе». ; # указываем целевую строку print $string1 =~ m/[aeiou]+/ ; # соответствует одной или нескольким гласным
Синтаксис достаточно гибок, чтобы указывать операции сопоставления с альтернативными разделителями, что позволяет легко избежать конфликта разделителей:
$string1 = 'Нэнси сказала, что «http://Hello/World.htm» не является допустимым адресом.' ; # целевая строка print $string1 =~ m@http://@ ; # сопоставление с использованием альтернативного разделителя регулярных выражений print $string1 =~ m{http://} ; # то же, что и предыдущее, но с другим разделителем print $string1 =~ m!http://! ; # то же, что и предыдущее, но другой разделитель.
Документ Here позволяет включать произвольное содержимое, описывая специальную конечную последовательность. Многие языки поддерживают это, включая PHP , сценарии bash , Ruby и Perl . Документ здесь начинается с описания того, какой будет конечная последовательность, и продолжается до тех пор, пока эта последовательность не появится в начале новой строки. [25]
Вот пример на Perl:
напечатать << КОНЕЦГЕРЕДОК ; Очень сложно закодировать строку с «определенными символами». Новые строки, запятые и другие символы могут вызвать конфликты разделителей. ЭНДОФГЕРЕДОК
Этот код напечатает:
Очень сложно закодировать строку с «определенными символами».Новые строки, запятые и другие символы могут вызвать конфликты разделителей.
Благодаря использованию специальной конечной последовательности в строке можно использовать любые символы.
Хотя защита ASCII в основном используется как механизм текстового кодирования двоичных данных, она представляет собой метод программирования и системного администрирования, который также помогает в некоторых обстоятельствах избежать коллизий разделителей. [26] [27] Этот метод отличается от других подходов, описанных выше, поскольку он более сложен и, следовательно, не подходит для небольших приложений и простых форматов хранения данных. В этом методе используется специальная схема кодирования, такая как base64 , чтобы гарантировать, что разделитель или другие значимые символы не появляются в передаваемых данных. Целью является предотвращение многоуровневого экранирования , например, двойных кавычек .
Этот метод используется, например, в технологии веб-разработки Microsoft ASP.NET и тесно связан с компонентом «VIEWSTATE» этой системы. [28]
Следующий упрощенный пример демонстрирует, как этот метод работает на практике.
В первом фрагменте кода показан простой HTML-тег , в котором значение VIEWSTATE содержит символы, несовместимые с разделителями самого HTML-тега:
<input type= "hidden" name= "__VIEWSTATE" value= "BookTitle:Нэнси больше не говорит " Привет, мир!" ." />
Этот первый фрагмент кода неправильно сформирован и поэтому не будет работать должным образом в развернутой системе «реального мира».
Для хранения произвольного текста в атрибуте HTML можно использовать сущности HTML . В данном случае """ заменяет двойную кавычку:
<input type= "hidden" name= "__VIEWSTATE" value= "BookTitle:Нэнси больше не говорит "Hello World!"." />
В качестве альтернативы можно использовать любую кодировку, не включающую символы, имеющие особое значение в контексте, например base64:
<input type= "hidden" name= "__VIEWSTATE" value= "Qm9va1RpdGxlOk5hbmN5IGRvZXNuJ3Qgc2F5ICJIZWxsbyBXb3JsZCEiIGFueW1vcmUu" />
Или процентное кодирование :
<input type= "hidden" name= "__VIEWSTATE" value= "BookTitle:Nancy%20doesn%27t%20say%20%22Hello%20World!%22%20anymore." />
Это предотвращает столкновение разделителей и гарантирует, что несовместимые символы не появятся внутри HTML-кода, независимо от того, какие символы встречаются в исходном (декодированном) тексте. [28]
{{citation}}
: CS1 maint: числовые имена: список авторов ( ссылка )