C encoding windows 1251: c# — How to find Encoding for 1251 codepage

Кодировка windows 1251 в сайтостроении

Кодировка windows 1251 была создана в начале 90 годов для русификации программных продуктов, выпускаемых корпорацией Microsoft:


Кодировка является 8-битной и включает в себя символы славянской группы языков, в которую входят русский, белорусский, украинский, болгарский, македонский, сербский – это дает преимущество перед остальными кириллическими кодировками (ISO 8859-5, KOI8-R, CP866). Однако у 1251-кодировки имеются и весомые недостатки:

  • 0xFF (25510) – это код, который зарезервирован для символа «я». В программах, которые не поддерживают чистый 8-ой бит, часто возникают непредсказуемые проблемы;
  • Нет псевдографики, которая присутствует в KOI8, CP866.

Ниже приведены символы из Code Page 1251 или сокращенно СР1251 (числа под символами являются кодом в шестнадцатеричной системе такого же символа в Юникоде):

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

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

Таблица кодировок не является универсальной, то есть, для расшифровки текста необходимо использовать ту, которая соответствует кодировке символов:


Для того чтобы html-документ корректно отобразился в браузере, необходимо указать используемую кодировку. Делается это следующим образом:

— между тегом <head> и закрывающим его </head> нужно прописать <meta http-equiv=»Content-Type» content=»text/html; charset=windows-1251″> — исходя из этой строки, браузер будет использовать символы русского алфавита для отображения текста на странице.

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


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

Для согласования расшифровки необходимо выполнить функцию mysql_query(«SET NAMES cp1251») – это означает, что преобразование из машинного кода будет осуществляться согласно таблице cp1251.

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

Для того чтобы для веб-ресурса была задана кодировка виндовс-1251, необходимо найти (или создать) файл .htaccess. Это файл, который хранит в себе дополнительные настройки и описания конфигураций web-сервера.

В нем для установки кодировки следует прописать следующие строки:

  • DefaultLanguage ru;
  • AddDefaultCharset windows-1251;
  • php_value default_charset «cp1251».

Таким образом, для корректного отображения текста должны совпадать его кодировка и таблица кодов, с помощью которой браузер будет расшифровывать символы. Для текстов, написанных на славянских языках, необходима win 1251 кодировка. Важно помнить, что элементы страниц и баз данных должны быть описаны с помощью одной таблицы кодов.

Таблица кодов символов Windows-1251



Windows-1251 — набор символов и кодировка, являющаяся стандартной 8-битной кодировкой для всех русских версий Microsoft Windows. Данная кодировка пользуется довольно большой популярностью в восточно-европейских странах. Windows-1251 выгодно отличается от других 8-битных кириллических кодировок (таких как CP866, KOI8-R и ISO 8859-5) наличием практически всех символов, использующихся в традиционной русской типографике для обычного текста (отсутствует только знак ударения). Кириллические символы идут в алфавитном порядке.
Windows-1251 также содержит все символы для близких к русскому языку языков: белорусского, украинского, сербского, македонского и болгарского.
На практике этого оказалось достаточно, чтобы кодировка Windows-1251 закрепилась в интернете вплоть до распространения UTF-8.

Таблица кодов символов Windows-1251

DecHexСимвол 
Dec
HexСимвол
00000NOP 12880Ђ
00101SOH 12981Ѓ
00202STX 13082
00303ETX 13183ѓ
00404EOT 13284
00505ENQ 13385
00606ACK 13486
00707BEL 13587
00808BS 13688
00909TAB 13789
0100ALF 1388AЉ
0110BVT 1398B
0120CFF 1408CЊ
0130DCR 1418DЌ
0140ESO 1428EЋ
0150FSI 1438FЏ
01610DLE 14490ђ
01711DC1 14591
01812DC2 14692
01913DC3 14793
02014DC4 14894
02115NAK 14995
02216SYN 15096
02317ETB 15197
02418CAN
 
15298
02519EM 15399
0261ASUB 1549Aљ
0271BESC 1559B
0281CFS 1569Cњ
0291DGS 1579Dќ
0301ERS 1589Eћ
0311FUS 1599Fџ
03220SP 160A0 
03321! 161A1Ў
03422« 162A2ў
03523# 163A3Ћ
03624$ 164A4¤
03725% 165A5Ґ
03826& 166A6¦
03927 167A7§
04028( 168A8Ё
04129) 169A9©
0422A* 170AAЄ
0432B+ 171AB«
0442C, 172AC¬
0452D 173AD­
0462E. 174AE®
0472F/ 175AFЇ
048300 176B0°
049311
 
177B1±
050322 178B2І
051333 179B3і
052344 180B4ґ
053355 181B5µ
054366 182B6
055377 183B7·
056388 184B8ё
057399 185B9
0583A: 186BAє
0593B; 187BB»
0603C< 188BCј
0613D= 189BDЅ
0623E> 190BEѕ
0633F? 191BFї
06440@ 192C0А
06541A 193C1Б
06642B 194C2В
06743C 195C3Г
06844D 196C4Д
06945E 197C5Е
07046F 198C6Ж
071 47G 199C7З
07248H 200C8И
07349I 201C9Й
0744AJ 202CAК
0754BK 203CBЛ
0764CL 204CCМ
0774DM 205CDН
0784EN 206CEО
0794FO 207CFП
08050P 208D0Р
08151Q 209D1С
08252R 210D2Т
08353S 211D3У
08454T 212D4Ф
08555U 213D5Х
08656V 214D6Ц
08757W 215D7Ч
08858X 216D8Ш
08959Y 217D9Щ
0905AZ 218DAЪ
0915B[ 219DBЫ
0925C\ 220DCЬ
0935D] 221DDЭ
0945E^ 222DEЮ
0955F_ 223DFЯ
09660` 224E0а
09761a 225E1б
09862b 226E2в
09963c 227E3г
10064d 228E4д
10165e 229E5е
10266f 230E6ж
10367g 231E7з
10468h 232E8и
10569i 233E9й
1066Aj 234EAк
1076Bk 235EBл
1086Cl 236ECм
1096Dm 237EDн
1106En 238EEо
1116Fo 239EFп
11270p 240F0р
11371q 241F1с
11472r 242F2т
11573s 243F3у
11674t 244F4ф
11775u 245F5х
11876v 246F6ц
11977w 247F7ч
12078x 248F8ш
12179y 249F9щ
1227Az 250FAъ
1237B{ 251FBы
1247C| 252FCь
1257D} 253FDэ
1267E~ 254FEю
1277FDEL 255FFя

Описание специальных (управляющих) символов

Первоначально управляющие символы таблицы ASCII (диапазон 00-31, плюс 127) были разработаны для того, чтобы управлять устройствами аппаратных средств, таких как телетайп, ввод данных на перфоленту и др.
Управляющие символы (кроме горизонтальной табуляции, перевода строки и возврата каретки) не используются в HTML-документах.

Cпециальные (управляющие) символы

КодОписание
NUL, 00Null, пустой
SOH, 01Start Of Heading, начало заголовка
STX, 02Start of TeXt, начало текста
ETX, 03End of TeXt, конец текста
EOT, 04End of Transmission, конец передачи
ENQ, 05Enquire. Прошу подтверждения
ACK, 06Acknowledgement. Подтверждаю
BEL, 07Bell, звонок
BS, 08Backspace, возврат на один символ назад
TAB, 09Tab, горизонтальная табуляция
LF, 0ALine Feed, перевод строки
Сейчас в большинстве языков программирования обозначается как \n
VT, 0BVertical Tab, вертикальная табуляция
FF, 0CForm Feed, прогон страницы, новая страница
CR, 0DCarriage Return, возврат каретки
Сейчас в большинстве языков программирования обозначается как \r
SO, 0EShift Out, изменить цвет красящей ленты в печатающем устройстве
SI, 0FShift In, вернуть цвет красящей ленты в печатающем устройстве обратно
DLE, 10Data Link Escape, переключение канала на передачу данных
DC1, 11
DC2, 12
DC3, 13
DC4, 14
Device Control, символы управления устройствами
NAK, 15Negative Acknowledgment, не подтверждаю
SYN, 16Synchronization. Символ синхронизации
ETB, 17End of Text Block, конец текстового блока
CAN, 18Cancel, отмена переданного ранее
EM, 19End of Medium, конец носителя данных
SUB, 1ASubstitute, подставить. Ставится на месте символа, значение которого было потеряно или испорчено при передаче
ESC, 1BEscape Управляющая последовательность
FS, 1CFile Separator, разделитель файлов
GS, 1DGroup Separator, разделитель групп
RS, 1ERecord Separator, разделитель записей
US, 1FUnit Separator, разделитель юнитов
DEL, 7FDelete, стереть последний символ.

Смотрите также:

URL коды символов ACSII

URL коды символов UTF-8 диапазон от U+0400 до U+04FF

HTML Кодирование URL

Таблица кодов символов кирилицы UTF-8





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


Введение

Я очень люблю программировать, я любитель и первый и последний раз заработал на программировании в далёком 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


Таблица KOI8-r

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


Наблюдение 3

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


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

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

Для меня такая цель не стояла. Мне достаточно определять кодировки в предположении, что там есть русский язык. И второе, определять нужно по небольшому количеству символов – на 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 определяются даже в случае отсутствия русских букв

Таблица Windows-1251

Windows-1251 (cp1251) — это стандартная 8-битная кодировка, разработанная компанией Microsoft. Она содержит практически все символы, которые Вы можете встретить на стандартной русской клавиатуре. Также 1251 имеет символы для таких языков, как белорусский, украинский, болгарский и сербский.

DEC

HEX

СИМВ

DEC

HEX

СИМВ

DEC

HEX

СИМВ

000

00

NOP

086

56

V

171

AB

«

001

01

SOH

087

57

W

172

AC

¬

002

02

STX

088

58

X

173

AD

003

03

ETX

089

59

Y

174

AE

®

004

04

EOT

090

5A

Z

175

AF

Ї

005

05

ENQ

091

5B

[

176

B0

°

006

06

ACK

092

5C

\

177

B1

±

007

07

BEL

093

5D

]

178

B2

І

008

08

BS

094

5E

^

179

B3

і

009

09

Табуляция

095

5F

_

180

B4

ґ

010

0A

LF

096

60

`

181

B5

µ

011

0B

VT

097

61

a

182

B6

012

0C

FF

098

62

b

183

B7

·

013

0D

CR

099

63

c

184

B8

Ё

014

0E

SO

100

64

d

185

B9

015

0F

SI

101

65

e

186

BA

Є

016

10

DLE

102

66

f

187

BB

»

017

11

DC1

103

67

g

188

BC

ј

018

12

DC2

104

68

h

189

BD

Ѕ

019

13

DC3

105

69

i

190

BE

Ѕ

020

14

DC4

106

6A

j

191

BF

Ї

021

15

NAK

107

6B

k

192

C0

А

022

16

SYN

108

6C

l

193

C1

Б

023

17

ETB

109

6D

m

194

C2

В

024

18

CAN

110

6E

n

195

C3

Г

025

19

EM

111

6F

o

196

C4

Д

026

1A

SUB

112

70

p

197

C5

Е

027

1B

ESC

113

71

q

198

C6

Ж

028

1C

FS

114

72

r

199

C7

З

029

1D

GS

115

73

s

200

C8

И

030

1E

RS

116

74

t

201

C9

Й

031

1F

US

117

75

u

202

CA

К

032

20

Пробел

118

76

v

203

CB

Л

033

21

!

119

77

w

204

CC

М

034

22

«

120

78

x

205

CD

Н

035

23

#

121

79

y

206

CE

О

036

24

$

122

7A

z

207

CF

П

037

25

%

123

7B

{

208

D0

Р

038

26

&

124

7C

|

209

D1

С

039

27

125

7D

}

210

D2

Т

040

28

(

126

7E

~

211

D3

У

041

29

)

127

7F



212

D4

Ф

042

2A

*

128

80

Ђ

213

D5

Х

043

2B

+

129

81

Ѓ

214

D6

Ц

044

2C

,

130

82

215

D7

Ч

045

2D

131

83

ѓ

216

D8

Ш

046

2E

.

132

84

217

D9

Щ

047

2F

/

133

85

218

DA

Ъ

048

30

0

134

86

219

DB

Ы

049

31

1

135

87

220

DC

Ь

050

32

2

136

88

221

DD

Э

051

33

3

137

89

222

DE

Ю

052

34

4

138

8A

Љ

223

DF

Я

053

35

5

139

8B

224

E0

а

054

36

6

140

8C

Њ

225

E1

б

055

37

7

141

8D

Ќ

226

E2

в

056

38

8

142

8E

Ћ

227

E3

г

057

39

9

143

8F

Џ

228

E4

д

058

3A

:

144

90

Ђ

229

E5

е

059

3B

;

145

91

230

E6

ж

060

3C

<

146

92

231

E7

з

061

3D

=

147

93

232

E8

и

062

3E

>

148

94

233

E9

й

063

3F

?

149

95

234

EA

к

064

40

@

150

96

235

EB

л

065

41

A

151

97

236

EC

м

066

42

B

152

98 ˜

237

ED

н

067

43

C

153

99

238

EE

о

068

44

D

154

9A

љ

239

EF

п

069

45

E

155

9B

240

F0

р

070

46

F

156

9C

њ

241

F1

с

071

47

G

157

9D

ќ

242

F2

т

072

48

H

158

9E

ћ

243

F3

у

073

49

I

159

9F

џ

244

F4

ф

074

4A

J

160

A0

245

F5

х

075

4B

K

161

A1

Ў

246

F6

ц

076

4C

L

162

A2

ў

247

F7

ч

077

4D

M

163

A3

Ј

248

F8

ш

078

4E

N

164

A4

¤

249

F9

щ

079

4F

O

165

A5

Ґ

250

FA

ъ

080

50

P

166

c # — закодировать XDocumnet из win-1251 в utf-8

Переполнение стека
  1. Товары
  2. Клиенты
  3. Случаи использования
  1. Переполнение стека Публичные вопросы и ответы
  2. Команды Частные вопросы и ответы для вашей команды
  3. предприятие Частные вопросы и ответы для вашего предприятия
  4. работы Программирование и связанные с ним технические возможности карьерного роста
  5. Талант Нанимать технический талант
  6. реклама Связаться с разработчиками по всему миру
,

sql server — кодировка кириллицы в C #

Переполнение стека
  1. Товары
  2. Клиенты
  3. Случаи использования
  1. Переполнение стека Публичные вопросы и ответы
  2. Команды Частные вопросы и ответы для вашей команды
  3. предприятие Частные вопросы и ответы для вашего предприятия
  4. работы Программирование и связанные с ним технические возможности карьерного роста
  5. Талант Нанимать технический талант
  6. реклама Связаться с разработчиками по всему миру
,
c # — HttpClient создает исключение System.ArgumentException: «windows-1251» не поддерживается имя кодировки Переполнение стека
  1. Товары
  2. Клиенты
  3. Случаи использования
  1. Переполнение стека Публичные вопросы и ответы
  2. Команды Частные вопросы и ответы для вашей команды
  3. предприятие Частные вопросы и ответы для вашего предприятия
  4. работы Программирование и связанные с ним технические возможности карьерного роста
  5. Талант Нанимать технический талант
  6. реклама Связаться с разработчиками по всему миру
.
Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *