Базовая кодировка Oracle, как увидеть

Обновлено: 01.07.2024

Это отрывок из книги Бубала Ганесана Advanced PL/SQL: The Definitive Reference.

Пакет UTL_ENCODE был представлен в выпуске Oracle версии 9i для кодирования и декодирования необработанных данных, прежде всего тела сообщения электронной почты, при их передаче между хостами. Этот пакет также помогает преобразовать файлы фрагментов в более организованные части пакета UTL_FILE.

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

В этом пакете пять подпрограмм для кодирования и декодирования. Они,

Функции BASE64_ENCODE и BASE64_DECODE

Функция ENCODE преобразует входной двоичный файл RAW в его закодированную форму BASE64, а функция DECODE принимает форму данных RAW в кодировке BASE64 и преобразует обратно в исходный формат.

Прототипы этих функций показаны ниже,

UTL_ENCODE.BASE64_ENCODE (r IN RAW) ВОЗВРАТ RAW;

UTL_ENCODE.BASE64_DECODE (r IN RAW) ВОЗВРАТ RAW;

· Параметр R содержит строку RAW

В приведенном ниже примере строка VARCHAR2 преобразуется в RAW с помощью функции UTL_RAW.CAST_RAW. После этого преобразования строка RAW затем кодируется в форму BASE64 с помощью функции UTL_ENCODE.BASE64_ENCODE. Эти закодированные данные RAW должны использоваться во время передачи, а на принимающей стороне эта строка должна быть преобразована обратно в исходную форму с помощью функции UTL_ENCODE.BASE64_DECODE. Затем исходную строку VARCHAR2 можно извлечь из этой строки RAW с помощью функции UTL_RAW. Функция CAST_TO_VARCHAR2 аналогична приведенному ниже примеру.

dbms_output.put_line('Исходная строка: '||l_vc_var1);

dbms_output.put_line('Исходная строка RAW: '||l_rw_var2);

dbms_output.put_line('Закодированная строка RAW: '||l_rw_var2);

dbms_output.put_line('Декодированная строка RAW: '||l_rw_var2);

dbms_output.put_line('Декодированная исходная строка: '||l_vc_var1);

Исходная строка: UTL_ENCODE

Исходная строка RAW: 55544C5F454E434F4445

Закодированная строка RAW: 5656524D5830564F5130394552513D3D

Расшифрованная строка RAW: 55544C5F454E434F4445

Расшифрованная исходная строка: UTL_ENCODE

Обучение Oracle от Дона Берлесона

Лучшие на сайте «Учебные курсы Oracle» находятся на расстоянии одного телефонного звонка! Вы можете пройти индивидуальное обучение Oracle от Дональда Берлесона прямо в своем магазине!


Бурлесон — американская команда


Примечание. Эта документация по Oracle была создана в качестве справочника по поддержке и обучению Oracle для использования нашими специалистами-консультантами по настройке производительности администраторов баз данных. Не стесняйтесь задавать вопросы на нашем форуме Oracle.

Проверьте опыт! Любой, кто рассматривает возможность использования услуг эксперта службы поддержки Oracle, должен самостоятельно проверить свои полномочия и опыт, а не полагаться на рекламу и самопровозглашенный опыт. Все законные эксперты Oracle публикуют свои квалификации Oracle.

Ошибки? Технология Oracle меняется, и мы стараемся обновлять нашу информацию о поддержке BC Oracle. Если вы обнаружите ошибку или у вас есть предложение по улучшению нашего контента, мы будем признательны за ваш отзыв. Просто электронная почта:


и укажите URL-адрес страницы.


Burleson Consulting

Оракул поддержки баз данных

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

Эта глава содержит следующую тему:

Сводка подпрограмм UTL_ENCODE

Таблица 250-1. Подпрограммы пакета UTL_ENCODE

Читает входную строку RAW, закодированную с основанием 64, и декодирует ее в исходное значение RAW

Кодирует двоичное представление значения RAW в элементы с основанием 64 и возвращает его в виде строки RAW

Декодирует строку из формата заголовка mime

Кодирует строку в формат заголовка mime

Читает входную строку формата varchar2 в кавычках для печати и декодирует ее в соответствующую строку RAW

Считывает входную строку RAW и кодирует ее в соответствующую строку печатного формата в кавычках

Декодирует текстовую строку, чувствительную к набору символов

Кодирует текстовую строку, чувствительную к набору символов

Читает входную строку формата RAW uuencode и декодирует ее в соответствующую строку RAW

Считывает входную строку RAW и кодирует ее в соответствующую строку формата uuencode

Функция BASE64_DECODE

Эта функция считывает входную строку RAW, закодированную с основанием 64, и декодирует ее в исходное значение RAW.

Таблица 250-2 Параметры функции BASE64_DECODE

Строка RAW, содержащая данные в кодировке Base 64. Нет параметров по умолчанию или необязательных параметров.

Таблица 250-3. Возвращаемые значения функции BASE64_DECODE

Содержит декодированную строку

Функция BASE64_ENCODE

Эта функция кодирует двоичное представление значения RAW в элементы с основанием 64 и возвращает его в виде строки RAW.

Таблица 250-4 Параметры функции BASE64_ENCODE

Значение RAW для кодирования. Нет параметров по умолчанию или необязательных параметров.

Таблица 250-5. Возвращаемые значения функции BASE64_ENCODE

Содержит закодированные элементы с основанием 64

Функция MIMEHEADER_DECODE

Эта функция принимает на вход "закодированное слово" вида:

Инкапсулируется в теги заголовка mime, которые предоставляют функции MIMEHEADER_DECODE информацию о том, как декодировать строку. Теги метаданных заголовка mime удаляются из входной строки и преобразуются в базовый набор символов базы данных следующим образом:

Если это платформа UTF16, преобразуйте закодированный текст из UTF16 в ASCII

Если это платформа EBCDIC, преобразуйте закодированный текст из EBCDIC в ASCII

Если это платформа ASCII или UTF8, преобразование не требуется

Строка декодируется с помощью декодирования с кавычками или base64, как указано в теге метаданных в закодированном слове. Полученный преобразованный и декодированный текст возвращается вызывающей стороне в виде строки VARCHAR2.

Таблица 250-6. Параметры функции MIMEHEADER_DECODE

Закодированные текстовые данные с тегами формата заголовка mime.

Таблица 250-7. Возвращаемые значения функции MIMEHEADER_DECODE

Закодированные текстовые данные с тегами формата заголовка mime

Функция MIMEHEADER_ENCODE

Эта функция возвращает в качестве вывода "закодированное слово" в форме:

Входной параметр buf — это кодируемый текст, который становится .

Значение равно "Q" или "B" для кодирования с возможностью печати в кавычках или кодирования base64 соответственно. Входной параметр ENCODING принимает в качестве допустимых значений UTL_ENCODE.QUOTED_PRINTABLE или UTL_ENCODE.BASE64 или NULL . Если NULL , в качестве значения по умолчанию выбирается кодировка с кавычками.

Значение указывается как входной параметр encode_charset . Если NULL , в качестве значения по умолчанию выбирается набор символов базы данных.

Процесс кодирования mimeheader включает преобразование входной строки buf в набор символов, указанный параметром encode_charset. Преобразованная строка кодируется либо в формат, пригодный для печати в кавычках, либо в формат с кодировкой base64. Теги заголовка mime добавляются и добавляются в начало.

Наконец, строка преобразуется в базовый набор символов базы данных:


Я реализовал это для отправки кириллических сообщений электронной почты через мой сервер MS Exchange.

upd: после небольшой корректировки я придумал это, так что теперь это работает в обе стороны:

Вы можете проверить это:

upd2: Хорошо, вот пример преобразования, который работает для CLOB, который я только что придумал. Попробуйте решить это для ваших капель. :)

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

В вашем втором обновлении есть небольшая ошибка: параметр «количество» в dbms_log.substr должен быть «наименьшим (substring_length, length (clobInBase64) - (substring_length * n + 1)). То, как вы написали, возвращает отрицательное значение, поэтому подстрока всегда пуста.

Кодирование BASE64 берет 3 байта входного потока и преобразует его в 4 * 3 байта. Каждый из этих 3 байтов сопоставляется с 64 различными символами (a-z, A-Z, 0-9, "+", "/" - таким образом вы получаете имя BASE64). Убедитесь, что значение substring_length кратно 4 для BASE64_DECODE , соответственно. целое кратное 3 для BASE64_ENCODE . Таким образом, ваша функция to_base64 может вернуть неверный результат.

Решение с utl_encode.base64_encode и utl_encode.base64_decode имеет одно ограничение: они работают только со строками до 32 767 символов/байт.

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

  • Для BASE64_ENCODE функция должна прочитать 3 байта и преобразовать их. В случае многобайтовых символов (например.öäüè€ хранится в UTF-8, также известном как AL32UTF8) 3 символа не обязательно также 3 байта. Чтобы всегда читать 3 байта, вы должны сначала преобразовать свой CLOB в BLOB.
  • Та же проблема возникает и для BASE64_DECODE . Функция должна прочитать 4 байта и преобразовать их в 3 байта. Эти 3 байта не обязательно являются 3 символами.
  • Обычно строка BASE64 содержит символ NEW_LINE ( ​​CR и/или LF ) через каждые 64 символа. Такие символы новой строки следует игнорировать при декодировании.

Принимая во внимание все это, полнофункциональное решение может быть следующим:

В Oracle есть функция для кодирования двоичного значения, особенно типа RAW, в base64: BASE64_ENCODE . Это имеет смысл. Я хочу превратить двоичный файл во что-то, что мне будет легче портировать между системами.

Однако, помимо приема двоичного RAW на вход, он также возвращает двоичный RAW на выходе. Я нахожу это чрезвычайно запутанным, поскольку цель base64 — кодировать байты в формате text.

Так что же на самом деле содержит этот выходной файл RAW? Как правильно преобразовать его в настоящий текстовый тип (например, VARCHAR2 )?

Кроме того, я предполагаю, что BASE64_DECODE ожидает, что его ввод будет в том же формате, что и вывод BASE64_ENCODE , но обратите внимание, если это не так.

Я специально использую Oracle 11.2, но сомневаюсь, что это изменилось с момента его появления. Не стесняйтесь исправлять меня, если я ошибаюсь в этом.


@JSapkota Да. Я связался с ним в вопросе. Если есть альтернатива, которая на самом деле возвращает текстовый тип, я более чем заинтересован.

использовали ли вы hextoraw для конвертации? выберите utl_raw.cast_to_varchar2(hextoraw('шестнадцатеричное значение')) из двойного;

@JSapkota Правда, я мог бы использовать это, чтобы вместо этого выдать это в шестнадцатеричном формате. Не ответ, а достойный обходной путь. Спасибо.

Вы пробовали использовать UTL_ENCODE.TEXT_ENCODE?. Если вы хотите закодировать конфиденциальные данные набора символов, я имею в виду текст, отправить в цель и декодировать исходный текст, тогда эта функция может быть подходящей.

1 Ответ 1

Чтобы понять вашу проблему и смоделировать ее, я создал один сценарий. Прежде всего, я хотел бы рассказать, как работает Base64 в целом.
1) Он принимает текст ASCII.
2) Преобразует его в шестнадцатеричные значения (преобразование десятичного числа в шестнадцатеричное).
3) Представляет текст в битах (группы в виде байтов).
4) Поскольку Base64 принимает три байта данных. То есть он принимает 24 бита данных и возвращает 32-битные закодированные символы. Таким образом, бит должен быть представлен в виде 6-битной строки.
5) Затем эта 6-битная строка будет преобразована в десятичное число.
6) Затем он выбирает символы ascii (A-Z, a-z, 0-1, + и /) в соответствии с десятичным числом, рассчитанным на шаге 4.

Теперь я хочу показать это на практике, а также показать, как кодировка Oracle Base64 возвращает значение RAW.
Допустим, мы хотим закодировать текст «ABCD».
1) Давайте преобразуем это в данные RAW, которые представляют собой шестнадцатеричные значения.

У нас есть шестнадцатеричные значения "ABCD", то есть "41424344".
2) Давайте закодируем этот шестнадцатеричный код, используя Base64. В Oracle у нас есть пакет UTL_ENCODE для его кодирования, который принимает RAW и возвращает закодированное значение как RAW.

Позвольте мне объяснить, как мы получили эти значения в соответствии с шагами кодирования, которые я упомянул выше.
1) Наш текст 'ABCD'.
2) Шестнадцатеричное представление: «41424344».
3) Двоичное представление текста, сгруппированного по байтам.

4) Битовое представление текста, сгруппированного по 6 битам.

(Добавляет знак '=' к выходному тексту, так как мы добавили 0, чтобы сделать его 6-битным)
5) Десятичное представление 6-битного представления текста.

6) Теперь давайте выберем символы base64 (A-Z, a-z, 0-9, +,/ всего 64 символа: 0-63) в соответствии с десятичными значениями.

Вывод: QUJDRA==
Но кодировка Oracle Base64 возвращает этот текст как RAW (шестнадцатеричные значения). Чтобы получить закодированную строку в виде текста, а не RAW, мы можем преобразовать ее в VARCHAR2.

Если мы преобразуем значение ASCII этого текста в шестнадцатеричное, мы получим закодированную строку, возвращаемую кодировкой Base64.

Теперь давайте преобразуем этот текст в шестнадцатеричный формат.

Мы получаем исходную закодированную строку


Теперь, чтобы вернуть мой текст к исходному тексту «ABCD», давайте его декодируем.

Читайте также: