Как исправить эту unicodedecodeerror, которая говорит «недопустимый байт продолжения»?

Формат 32-битного целого числа со знаком

Поразрядные (побитовые) операторы работают с 32-битными целыми числами в их двоичном представлении.
Двоичные числа представляют из себя строки, состоящие из нулей и единиц, в которых значение каждой единицы определяется ее позицией в данной строке.

Вот так, например, вы­глядият числа, записанные в формате 32-разрядного целого двоичного числа:

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

Чтобы не путать, в какой системе счисления записано число, обычно в индексе пишут основание системы счисления, в которой оно записао. Например, число 5 в десятичной системе – 510,а в двоичной – 1012.

Чтобы перевести число в двоичную систему счисления необходимо делить его нацело на 2 пока не получим , затем необходимо записать все остатки от деления в обратном порядке.

Например, число 18, записываемое в двоичной системе счисления, имеет значение:

Теперь записываем полученные остатки от деления в обратном порядке

Получаем, что число 18 в двоичном представлении будет выглядеть как 00000000000000000000000000010010 (обратите внимание, число состоит ровно из 32-битов), или, сокращенно, как 10010. Эти пять значимых битов и определяют фактическое значение числа 18

Для преобразования из двоичной системы в десятичную используют формулу, состоящую из степеней основания 2:

a = a * 2 + a1 * 21 + a2 * 22 + … + an * 2n

где а – число в десятичной системе счисления; a, a1, … an – цифры данного числа в двоичном представлении. Причём a — это последняя или правая цифра, а an – первая.

Например, возьмём двоичное число 1010012. Для перевода в десятичное запишем его как сумму по разрядам следующим образом:

1 * 25 +  * 24 + 1 * 23 +  * 22 +  * 21 + 1 * 2 = 41

Перепишем тоже самое, возведя в степени все основания 2:

1 * 32 +  * 16 + 1 * 8 +  * 4 +  * 2 + 1 * 1 = 41

Можно записать это в виде таблицы следующим образом:

512(210) 256(29) 128(28) 64(26) 32(25) 16(24) 8(23) 4(22) 2(21) 1(2)
1 1 1
+32 +0 +8 +0 +0 +1

Положительные числа хранятся в настоящем двоичном формате, в котором все биты, кроме знакового (крайний левый), представляют степени двойки: первый бит (справа) соответствует 2, второй – 21, третий – 22 и т. д. Если какие-либо биты не используются, они считаются равными нулю.

Теперь под каждой двоичной единицей напишите её эквивалент в нижней строчке таблицы и сложите получившиеся десятичные числа. Таким образом, двоичное число 1010012 равнозначно десятичному 4110.

Термин «целые числа со знаком» означает, что в этой форме могут быть представлены как положительные, так и отрицательные целые числа.

Отрицательные числа также хранятся в двоичном коде, но в формате, который на­зывается «дополнителъным кодом» (англ. two’s complement, иногда twos-complement).

Представление в «дополнительном коде» означает, что отрицательное значение числа (например 5 и -5) получается путем инвертирования числа (операция «побитовое НЕ», также известное как «обратный код» или «первое дополнение») и прибавлением к инверсии единицы («второе дополнение»).

К примеру, определим двоичное представление числа -5. Начнём с двоичного представления его абсолютного значения (5):

00000000000000000000000000000101

Инвертируем все разряды числа (заменим на 1, а 1 на ), получая таким образом обратный код (первое дополнение) числа 5:

11111111111111111111111111111010

Дополнительный код (второе дополнение) двоичного числа получается добавлением 1 (обычным двоичным сложением) к младшему значащему разряду его первого дополнения:

11111111111111111111111111111010 + 
                               1 = 
11111111111111111111111111111011

Итак, мы получили:

-5 = 11111111111111111111111111111011

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

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

При изучении побитовых операторов вам могут пригодиться функции, которые облегчают перевод чисел из десятичного в двоичное представление и наоборот:

Выполнить код »
Скрыть результаты

UTF-8 против UTF-16

Как я уже упоминал, UTF-8 – не единственный метод кодирования символов Unicode – существует также UTF-16. Эти методы различаются количеством байтов, необходимых для хранения символа. UTF-8 кодирует символ в двоичную строку из одного, двух, трех или четырех байтов. UTF-16 кодирует символ Unicode в строку из двух или четырех байтов.

Это различие видно из их названий. В UTF-8 наименьшее двоичное представление символа составляет один байт или восемь битов. В UTF-16 наименьшее двоичное представление символа составляет два байта или шестнадцать бит.

И UTF-8, и UTF-16 могут переводить символы Unicode в двоичные файлы, удобные для компьютера, и обратно. Однако они несовместимы друг с другом. Эти системы используют разные алгоритмы для сопоставления кодовых точек с двоичными строками, поэтому двоичный вывод для любого заданного символа будет отличаться от обоих методов:

символ Двоичная кодировка UTF-8 Двоичная кодировка UTF-16
А 01000001 01000001 11011000 00001110 11011111
𠜎 11110000 10100000 10011100 10001110 01000001 11011000 00001110 11011111

Кодировка UTF-8 предпочтительнее UTF-16 на большинстве веб-сайтов, потому что она использует меньше памяти. Напомним, что UTF-8 кодирует каждый символ ASCII всего одним байтом. UTF-16 должен кодировать эти же символы в двух или четырех байтах. Это означает, что текстовый файл на английском языке с кодировкой UTF-16 будет как минимум вдвое больше размера того же файла с кодировкой UTF-8.

UTF-16 более эффективен, чем UTF-8, только на некоторых неанглоязычных сайтах. Если веб-сайт использует язык с символами, находящимися дальше в библиотеке Unicode, UTF-8 будет кодировать все символы как четыре байта, тогда как UTF-16 может кодировать многие из тех же символов только как два байта. Тем не менее, если ваши страницы заполнены буквами ABC и 123, придерживайтесь UTF-8.

Побитовое исключающее ИЛИ (^)

Побитовое исключающее ИЛИ () выполняет исключающую дизъюнкцию над каждой парой битов, которые стоят на одинаковых позициях в двоичных представлениях операндов. Другими словами, результат равен , если оба соответствующих бита операндов равны между собой; в противном случае, двоичный разряд результата равен 1.

Таблица истинности для этой операции выглядит так:

a b a ^ b
1 1
1 1
1 1

В следующем примере поразрядное исключающее ИЛИ выполняется для чисел 38 и 3:

Выполнить код »
Скрыть результаты

Этот пример отличается от предыдущего только тем, что второй бит результата обнуляется, поскольку в обоих операндах он равен 1. Все остальные единичные биты переходят в результат, потому что у них нет пары. В итоге, получаем 1001012, или 3710.

Исключающее ИЛИ () с нулём в качестве одного из операндов можно использовать для округления математических выражений:

Выполнить код »
Скрыть результаты

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

Сдвиг битов вправо с заполнением нулями (>>>)

Оператор (сдвиг битов вправо с заполнением нулями) сдвигает все биты числа вправо на указанное количество разрядов. В отличие от сдвига вправо с со­хранением знака , теперь пустые слева биты заполняются нулями независимо от знака числа. Знаковый бит становится равным , поэтому результат всегда положителен.

В следующем примере выполняется сдвиг битов вправо на 2 разряда для чисел 9 и -9:

Выполнить код »
Скрыть результаты

При сдвиге вправо с заполнением нулями отрицательное число в двоичном формате обрабатывается как положительное число. Учитывая, что отрицательное число является дополнением его абсолютного значения до двух, число становится очень большим, например, результатом -9 >>> 2 будет 1073741821 в десятичном формате.

Расшифровка мира кодировки UTF-8

Это было много слов о словах, поэтому давайте резюмируем то, что мы рассмотрели:

  1. Компьютеры хранят данные, включая текстовые символы, как двоичные (единицы и нули).
  2. ASCII был ранним способом кодирования или отображения символов в двоичный код, чтобы компьютеры могли их хранить. Однако в ASCII не было достаточно места для представления нелатинских символов и чисел в двоичном формате.
  3. Юникод был решением этой проблемы. Юникод присваивает уникальный «код» каждому символу на каждом человеческом языке.
  4. UTF-8 – это метод кодировки символов Unicode. Это означает, что UTF-8 берет кодовую точку для данного символа Юникода и переводит ее в строку двоичного кода. Он также делает обратное, считывая двоичные цифры и преобразуя их обратно в символы.
  5. UTF-8 в настоящее время является самым популярным методом кодирования в Интернете, поскольку он может эффективно хранить текст, содержащий любой символ.
  6. UTF-16 – еще один метод кодирования, но он менее эффективен для хранения текстовых файлов (за исключением тех, которые написаны на некоторых неанглийских языках).

Перевод Unicode – это не то, о чем большинству из нас нужно думать при просмотре или разработке веб-сайтов, и именно в этом суть – создать бесшовную систему обработки текста, которая работает для всех языков и веб-браузеров. Если он работает хорошо, вы этого не заметите.

Но если вы обнаружите, что страницы вашего веб-сайта занимают чрезмерно много места или если ваш текст завален буквами and и, пора применить ваши новые знания о UTF-8.

Источник записи: https://blog.hubspot.com

Как можно посмотреть байтовое представление Double

Класс BitConverter позволяет получить байтовое представление базовых типов или наоборот преобразовать байтовое представление в базовый тип.

Double занимает 8 байтов в памяти и метод возвращает нам массив из 8 элементов — всё сходится.

Но для разбора удобнее числа представлять в двоичной системе исчисления. Можно для этого каждый элемент массива представить в двоичном виде.

А можно воспользоваться методом — он возвращает 64 битное целое число, которое в двоичном виде соответствует байтовому представлению числа типа double.

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

Поехали

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

У Джона Скита есть две коротенькие статьи на эту тему, первая: Binary floating point and .NET — про double и float, вторая: Decimal floating point in .NET — про decimal (в этой статье я не касаюсь Decimal).

Сам Скит рекомендует к прочтению эту статью: Floating Point in .NET part 1: Concepts and Formats — она более подробная и позволит более основательно разобраться в вопросе.

Также в процессе подготовки этого материала я нашёл статью на русском: Взгляд со стороны: Стандарт IEEE754 — она в целом о стандарте хранения чисел IEEE754, статья основательная, но довольно абстрактная и её не назовёшь лёгким, доступным материалом.

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

Кодировка UTF-8 как кодировка переменной длины

В UTF-8 символы кодируются следующим образом:

  1. Если кодируется ASCII-символ, то старший бит устанавливается в 0, а остальные 7 бит представляют код ASCII-символа.
  2. Иначе, первые 8 бит содержат n единиц, где n – количество байт в кодируемом символе (то есть, минимум 2 единицы), за которыми следует 0. Остальные биты представляют часть кода символа.
  3. Следующие блоки по 8 бит начинаются на 10 (старший бит установлен в 1, следующий – в 0), а остальные биты представляют часть кода символа.

Максимальная длина кода символа в UTF-8 – 6 байт. Минимальная – 1 байт.

Пример:

Таким образом, технически UTF-8 может кодировать любую последовательность из UTF-32.

Следует заметить, что текущая версия стандарта Unicode 6 предполагает максимальный код 10FFFF16, для кодирования которого в UTF-8 достаточно 4 байт.

Теоретически, возможно кодирование более 31 бита в UTF-8, однако сейчас это не используется. Тем не менее, если первые 8 бит установлены в 1, то следующие 8 бит тоже могут быть интерпретированы как количество байт в коде.

Например:

Примеры кодирования:

UCS Код UCS (двоичный) Символ Код UTF-8 Код UTF-8 (двоичный) Значащие биты UTF-8
007316 0000 0000 0111 0011 Латинская s 7316 0111 0011 1110011
041A16 0000 0100 0001 1010 Киррилическая К D09A16 1101 0000 1001 1010 10000 011010
090416 0000 1001 0000 0100 Индийская ऄ (“А”) E0A48416 1110 0000 1010 0100 1000 0100 0000 100100 000100
9DDF16 1001 1101 1101 1111 鷟 (“феникс”) E9B79F16 1110 1001 1011 0111 1001 1111 1001 110111 011111
1033016 0001 0000 0011 0011 0000 Готическая 𐌰 (“Ахса”) F0908CB016 1111 0000 1001 0000 1000 1100 1011 0000 000 010000 001100 110000
1F60416 0001 1111 0110 0000 0100 Смайлик F09F988416 1111 0000 1001 1111 1001 1000 1000 0100 000 011111 011000 000100

Пример реализации алгоритмов кодирования и декодирования на С++:

История создания

До появления Unicode UTF-8 широко использовались другие кодировки (ASCII, ISO/IEC 646, ISO/IEC 8859, KOI8, Windows-125x).

Впервые кодировка UTF-8 была официально представлена на конференции USENIX в Сан Диего в январе 1993. От других мультибайтных кодировок ее отличала полная совместимость с ASCII: все символы ASCII в UTF-8 кодируются 7 битами. Каждый символ кодировки, отличный от ASCII, состоит из ведущего байта, указывающего длину последовательности, и одного или нескольких продолжающих байт. Такой принцип позволяет определить длину последовательности только по первому байту. Коды символов ASCII, ведущих и продолжающих байт не пересекаются, что позволяет легко найти начало последовательности простым откатом назад максимум на пять байт.

График изменения популярности кодировок в интернете

В ноябре 2003 года стандартом RFC-3629 максимальная длина последовательности UTF-8 была ограничена четырьмя байтами, однако потенциально UTF-8 позволяет использовать последовательности вплоть до шести байт.
На сегодняшний день самой распространенной кодировкой является UTF-8. Она включает в себя более двух миллионов символов: все возможные современные алфавиты, цифры, знаки препинания, математические и специальные символы, музыкальные знаки и символы вымерших форм письменности. А резерва UTF-8 хватит для размещения более двух миллиардов символов. Так что о смене кодировки в ближайшее время задумываться не придётся.

Однако торжество современных технологий — явление относительно новое. Согласно Google, самой распространенной в интернете кодировкой UTF-8 стала только в 2008 году — тогда ее использовали чуть более чем 25% проиндексированных веб-страниц. А еще в 2006 UTF-8 использовали менее чем 10% веб-страниц.

Стремительный рост популярности кодировки UTF-8 связан с целым рядом ее преимуществ перед предшественницами.

GB2312、GBK、GB18030

Кривые орехи кажутся идеальными, этого достаточно! !

Но когда дело дошло до Китая, китайцы увидели достаточно шаров. В Великом Китае около 80 000 человек. Эти 255 находятся далеко.

Поэтому китайцы изобрели свой собственный набор символов GB2312, который был выпущен Национальным управлением стандартов Китая в 1980 году и начал применяться 1 мая 1981 года. Стандартный номер — GB2312-1980. Это код, который может быть распознан компьютером и подходит для обмена информацией между системой обработки китайских символов и системами связи китайских символов. Стандарт GB 2312 содержит в общей сложности 6763 китайских иероглифа, в том числе 3755 китайских символов первого уровня и 3008 китайских символов второго уровня. В то же время GB 2312 включает латинские буквы, греческие буквы, японские буквы хирагана и катакана и русские буквы кириллицы. 682 символа полной ширины. Появление GB 2312 в основном отвечает потребностям китайских иероглифов в компьютерной обработке. Содержащиеся в нем китайские иероглифы покрывают 99,75% частоты использования в материковом Китае.

Таким образом, китайский народ самостоятельно исследовал и разработал и отменил странные символы после 127-го. Правило: значение символа меньше 127 совпадает с оригиналом, но когда два символа больше 127 объединены, это означает китайский символ. Первый байт (он назвал его старшим байтом) используется от 0xA1 до 0xF7, за которым следует Один байт (младший байт) имеет значение от 0xA1 до 0xFE, поэтому мы можем комбинировать более 7000 упрощенных китайских символов. В этих кодах мы также скомпилировали математические символы, латинские греческие буквы и японские псевдонимы. Даже исходные числа, знаки препинания и буквы в ASCII были перекодированы с помощью двухбайтовых кодов. Это то, что часто называют символом «полной ширины», а символы ниже 127 называются символами «полуширины».

Однако GB 2312 не может обрабатывать редкие символы, встречающиеся в именах древних китайцев и т. Д., Что привело к появлению китайского набора символов GBK и GB 18030.

GBK — это стандарт расширения внутреннего кода китайского иероглифа, K — начальная часть «расширения» в расширенном китайском пиньине. Английское полное название — китайская спецификация внутреннего кода. Стандарт кодирования GBK совместим с GB2312, который содержит в общей сложности 21 003 китайских и 883 символов и обеспечивает 1894 кодовых пункта для создания символов. Упрощенные и традиционные символы объединяются в одну библиотеку.

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

Набор символовКомпьютерная системаМинистерство информационной индустрииГосударственное бюро качества и технического надзораИнформационные технологиихарактерМонголияКореяУйгурскийхарактерОбязательные стандарты

Вышеуказанные кодыСовместим с существующими кодами ANSI (не включая коды расширения)В противном случае китайцы используют GBK, американцы используют ANSI, а китайцы вынуждены переключаться назад на коды ANSI, чтобы увидеть американские вещи.

Три системы счисления.

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

Машина «думает» байтами. Байт состоит из 8 бит. Бит может содержать одно значение: 0 или 1. Так что в принципе, неплохо иметь представление и о восьмеричной системе счисления.Однако машинный код отображается в различных редакторах в виде шестнадцатеричного значения — оно более удобно для восприятия, так что всё же остановимся на трёх обязательно необходимых программисту системах счисления.

Макет кодовой страницы

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

UTF-8
_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _A _B _C _D _E _F
0_ NUL0000 SOH00011 STX00022 ETX00033 EOT00044 ENQ00055 ACK00066 BEL00077 BS00088 HT00099 LF000A10 VT000B11 FF000C12 CR000D13 SO000E14 SI000F15
1_ DLE001016 DC1001117 DC2001218 DC3001319 DC4001420 NAK001521 SYN001622 ETB001723 CAN001824 EM001925 SUB001A26 ESC001B27 FS001C28 GS001D29 RS001E30 US001F31
2_ SP002032 !002133 «002234 #002335 $002436 %002537 &002638 002739 (002840 )002941 *002A42 +002B43 ,002C44 002D45 .002E46 002F47
3_ 003048 003149 003250 003351 003452 003553 003654 003755 003856 003957 003A58 ;003B59 <003C60 =003D61 >003E62 ?003F63
4_ @004064 A004165 B004266 C004367 D004468 E004569 F004670 G004771 H004872 I004973 J004A74 K004B75 L004C76 M004D77 N004E78 O004F79
5_ P005080 Q005181 R005282 S005383 T005484 U005585 V005686 W005787 X005888 Y005989 Z005A90 005B91 \005C92 005D93 ^005E94 _005F95
6_ `006096 a006197 b006298 c006399 d0064100 e0065101 f0066102 g0067103 h0068104 i0069105 j006A106 k006B107 l006C108 m006D109 n006E110 o006F111
7_ p0070112 q0071113 r0072114 s0073115 t0074116 u0075117 v0076118 w0077119 x0078120 y0079121 z007A122 {007B123 |007C124 }007D125 ~007E126 DEL007F127
8_ +00128 +01129 +02130 +03131 +04132 +05133 +06134 +07135 +08136 +09137 +0A138 +0B139 +0C140 +0D141 +0E142 +0F143
9_ +10144 +11145 +12146 +13147 +14148 +15149 +16150 +17151 +18152 +19153 +1A154 +1B155 +1C156 +1D157 +1E158 +1F159
A_ +20160 +21161 +22162 +23163 +24164 +25165 +26166 +27167 +28168 +29169 +2A170 +2B171 +2C172 +2D173 +2E174 +2F175
B_ +30176 +31177 +32178 +33179 +34180 +35181 +36182 +37183 +38184 +39185 +3A186 +3B187 +3C188 +3D189 +3E190 +3F191
2-byteC_ 0000192 0040193 Latin0080194 Latin00C0195 Latin0100196 Latin0140197 Latin0180198 Latin01C0199 Latin0200200 IPA0240201 IPA0280202 IPA02C0203 accents0300204 accents0340205 Greek0380206 Greek03C0207
2-byteD_ Cyril0400208 Cyril0440209 Cyril0480210 Cyril04C0211 Cyril0500212 Armeni0540213 Hebrew0580214 Hebrew05C0215 Arabic0600216 Arabic0640217 Arabic0680218 Arabic06C0219 Syriac0700220 Arabic0740221 Thaana0780222 N’Ko07C0223
3-byteE_ Indic0800*224 Misc.1000225 Symbol2000226 Kana, CJK3000227 CJK4000228 CJK5000229 CJK6000230 CJK7000231 CJK8000232 CJK9000233 AsianA000234 HangulB000235 HangulC000236 HangulD000237 PUAE000238 FormsF000239
4‑byteF_ SMP, SIP10000*240 40000241 80000242 SSP, SPUAC0000243 SPUA-B100000244 140000245 180000246 1C0000247 5-byte200000*248 5-byte1000000249 5-byte2000000250 5-byte3000000251 6-byte4000000*252 6-byte40000000253 254 255

Оранжевые ячейки с большой точкой являются байтами продолжения. Шестнадцатеричное число, указанное после знака «+», представляет собой значение шести бит, которые они добавляют.

Белые ячейки — это ведущие байты для последовательности из нескольких байтов, длина показана слева от строки. Текст показывает блоки Unicode, закодированные последовательностями, начинающимися с этого байта, а шестнадцатеричная кодовая точка, показанная в ячейке, является самым младшим символьным значением, закодированным с использованием этого старшего байта.

Красные клетки никогда не должны появляться в действительной последовательности UTF-8. Первые два (C0 и C1) могли использоваться только для недопустимого «чрезмерного кодирования» символов ASCII (то есть, пытаясь закодировать 7-битное значение ASCII между 0 и 127, используя два байта вместо одного, см. Ниже). Оставшиеся красные ячейки указывают ведущие байты последовательностей, которые могут только кодировать числа, превышающие предел 0x10FFFF в Юникоде, или которые также никогда не использовались в исходном проекте для 31 бита (FE и FF).

Розовые ячейки являются ведущими байтами для последовательности из нескольких байтов, из которых допустимы некоторые, но не все возможные последовательности продолжения. E0 и F0 могут начинать сглаженные кодировки, в этом случае отображается самая низкая незашифрованная кодовая точка, помеченная звездочкой «*». F4 может запускать кодовые точки более 0x10FFFF, которые являются недопустимыми. ED может начать кодирование суррогатной половины, которая не может быть закодирована в UTF-16 и также недействительна.

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: