Кодирование base64 в MySQL

Я хочу выбрать blob col из одной таблицы, base64 закодировать его и вставить в другие таблицы. Есть ли способ сделать это без циклического отключения данных из БД и через мое приложение?

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
50
0
125 021
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Похоже, что нет, хотя это было запрошено, и для этого есть UDF.

Обновлено: Или есть… это. Фу.

«О… М… Г…», - сказал парень, который покупает книгу о драконах, чтобы он мог построить парсер LALR (1) как sproc.

BCS 11.12.2008 08:30

Для заинтересованных пока это единственные альтернативы:

1) Использование этих функций:

http://wi-fizzle.com/downloads/base64.sql

2) Если у вас уже есть sys_eval UDF (Linux), вы можете сделать это:

sys_eval(CONCAT("echo '",myField,"' | base64"));

Известно, что первый метод медленный. Проблема со вторым состоит в том, что кодирование на самом деле происходит «вне» MySQL, что может иметь проблемы с кодированием (помимо рисков безопасности, которые вы добавляете с помощью функций sys_ *).

К сожалению, нет скомпилированной версии UDF (которая должна быть быстрее) или встроенной поддержки в MySQL (Posgresql поддерживает это!).

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

Вероятно, вы захотите вставить в это эхо -n, чтобы оно не добавляло новую строку.

Paul Rubel 01.08.2013 22:45
Ответ принят как подходящий

Я искал то же самое и только что увидел, что в MySQL 5.6 есть пара новых строковых функций, поддерживающих эту функциональность: TO_BASE64 и FROM_BASE64.

Функции из http://wi-fizzle.com/downloads/base64.sql содержат некоторую ошибку, когда в закодированной строке 32 байта (пробел), например BASE64_ENCODE (CONCAT (CHAR (15), CHAR (32))). Вот исправленная функция

DELIMITER $$

USE `YOUR DATABASE`$$

DROP TABLE IF EXISTS core_base64_data$$
CREATE TABLE core_base64_data (c CHAR(1) BINARY, val TINYINT)$$
INSERT INTO core_base64_data VALUES 
('A',0), ('B',1), ('C',2), ('D',3), ('E',4), ('F',5), ('G',6), ('H',7), ('I',8), ('J',9),
('K',10), ('L',11), ('M',12), ('N',13), ('O',14), ('P',15), ('Q',16), ('R',17), ('S',18), ('T',19),
('U',20), ('V',21), ('W',22), ('X',23), ('Y',24), ('Z',25), ('a',26), ('b',27), ('c',28), ('d',29),
('e',30), ('f',31), ('g',32), ('h',33), ('i',34), ('j',35), ('k',36), ('l',37), ('m',38), ('n',39),
('o',40), ('p',41), ('q',42), ('r',43), ('s',44), ('t',45), ('u',46), ('v',47), ('w',48), ('x',49),
('y',50), ('z',51), ('0',52), ('1',53), ('2',54), ('3',55), ('4',56), ('5',57), ('6',58), ('7',59),
('8',60), ('9',61), ('+',62), ('/',63), ('=',0) $$

DROP FUNCTION IF EXISTS `BASE64_ENCODE`$$

CREATE DEFINER=`YOUR DATABASE`@`%` FUNCTION `BASE64_ENCODE`(input BLOB) RETURNS BLOB
    DETERMINISTIC
    SQL SECURITY INVOKER
BEGIN
    DECLARE ret BLOB DEFAULT '';
    DECLARE done TINYINT DEFAULT 0;
    IF input IS NULL THEN
        RETURN NULL;
    END IF;
each_block:
    WHILE NOT done DO BEGIN
        DECLARE accum_value BIGINT UNSIGNED DEFAULT 0;
        DECLARE in_count TINYINT DEFAULT 0;
        DECLARE out_count TINYINT;
each_input_char:
        WHILE in_count < 3 DO BEGIN
            DECLARE first_char BLOB(1);

            IF LENGTH(input) = 0 THEN
                SET done = 1;
                SET accum_value = accum_value << (8 * (3 - in_count));
                LEAVE each_input_char;
            END IF;

            SET first_char = SUBSTRING(input,1,1);
            SET input = SUBSTRING(input,2);

            SET accum_value = (accum_value << 8) + ASCII(first_char);
            SET in_count = in_count + 1;
        END; END WHILE;

        -- We've now accumulated 24 bits; deaccumulate into base64 characters
        -- We have to work from the left, so use the third byte position and shift left
        CASE
            WHEN in_count = 3 THEN SET out_count = 4;
            WHEN in_count = 2 THEN SET out_count = 3;
            WHEN in_count = 1 THEN SET out_count = 2;
            ELSE RETURN ret;
        END CASE;

        WHILE out_count > 0 DO BEGIN
            BEGIN
                DECLARE out_char CHAR(1);
                DECLARE base64_getval CURSOR FOR SELECT c FROM core_base64_data WHERE val = (accum_value >> 18);
                OPEN base64_getval;
                FETCH base64_getval INTO out_char;
                CLOSE base64_getval;
                SET ret = CONCAT(ret,out_char);
                SET out_count = out_count - 1;
                SET accum_value = accum_value << 6 & 0xffffff;
            END;
        END; END WHILE;
        CASE
            WHEN in_count = 2 THEN SET ret = CONCAT(ret,'=');
            WHEN in_count = 1 THEN SET ret = CONCAT(ret,'==');
            ELSE BEGIN END;
        END CASE;

    END; END WHILE;
    RETURN ret;
END$$

DELIMITER ;

Мне пришлось заменить YOUR DATABASE моим именем db в операторе USE и поместить мое имя пользователя и имя хоста в DEFINER = ... @ .. часть создания функции. Кроме того, в этой части отсутствует определение таблицы core_base64_data, но она ссылается на нее. На исходной странице таблица называется base64_data.

Ivan Kurmanov 30.12.2013 15:14

Я предложил отредактировать, чтобы исправить вышеупомянутые проблемы (см. Предыдущий комментарий).

Ivan Kurmanov 30.12.2013 15:21

Неполный, core_base64_data не существует.

Marek 12.10.2015 12:42

Исходная ссылка мертва, эта пока работает: MySQL-url-base64-кодировать-декодировать-функция

Grzegorz Smulko 17.12.2015 16:57

Если вам это нужно для <5.6, я наткнулся на этот UDF, который, кажется, работает нормально:

https://github.com/y-ken/mysql-udf-base64

SELECT `id`,`name`, TO_BASE64(content) FROM `db`.`upload`

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

Еще одна пользовательская реализация, не требующая таблицы поддержки:

drop function if exists base64_encode;
create function base64_encode(_data blob)
returns text
begin
    declare _alphabet char(64) default 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    declare _lim int unsigned default length(_data);
    declare _i int unsigned default 0;
    declare _chk3 char(6) default '';
    declare _chk3int int default 0;
    declare _enc text default '';

    while _i < _lim do
        set _chk3 = rpad(hex(binary substr(_data, _i + 1, 3)), 6, '0');
        set _chk3int = conv(_chk3, 16, 10);
        set _enc = concat(
            _enc
            ,                  substr(_alphabet, ((_chk3int >> 18) & 63) + 1, 1)
            , if (_lim-_i > 0, substr(_alphabet, ((_chk3int >> 12) & 63) + 1, 1), '=')
            , if (_lim-_i > 1, substr(_alphabet, ((_chk3int >>  6) & 63) + 1, 1), '=')
            , if (_lim-_i > 2, substr(_alphabet, ((_chk3int >>  0) & 63) + 1, 1), '=')
        );
        set _i = _i + 3;
    end while;

    return _enc;
end;

drop function if exists base64_decode;
create function base64_decode(_enc text)
returns blob
begin
    declare _alphabet char(64) default 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    declare _lim int unsigned default 0;
    declare _i int unsigned default 0;
    declare _chr1byte tinyint default 0;
    declare _chk4int int default 0;
    declare _chk4int_bits tinyint default 0;
    declare _dec blob default '';
    declare _rem tinyint default 0;
    set _enc = trim(_enc);
    set _rem = if (right(_enc, 3) = '===', 3, if (right(_enc, 2) = '==', 2, if (right(_enc, 1) = '=', 1, 0)));
    set _lim = length(_enc) - _rem;

    while _i < _lim
    do
        set _chr1byte = locate(substr(_enc, _i + 1, 1), binary _alphabet) - 1;
        if (_chr1byte > -1)
        then
            set _chk4int = (_chk4int << 6) | _chr1byte;
            set _chk4int_bits = _chk4int_bits + 6;

            if (_chk4int_bits = 24 or _i = _lim-1)
            then
                if (_i = _lim-1 and _chk4int_bits != 24)
                then
                    set _chk4int = _chk4int << 0;
                end if;

                set _dec = concat(
                    _dec
                    ,                        char((_chk4int >> (_chk4int_bits -  8)) & 0xff)
                    , if (_chk4int_bits >  8, char((_chk4int >> (_chk4int_bits - 16)) & 0xff), '\0')
                    , if (_chk4int_bits > 16, char((_chk4int >> (_chk4int_bits - 24)) & 0xff), '\0')
                );
                set _chk4int = 0;
                set _chk4int_bits = 0;
            end if;
        end if;
        set _i = _i + 1;
    end while;

    return substr(_dec, 1, length(_dec) - _rem);
end;

Суть

Вы должны преобразовать кодировку после декодирования: convert(base64_decode(base64_encode('ёлка')) using utf8)

создать шифрование таблицы (имя пользователя varchar (20), пароль varbinary (200))

вставить в зашифрованные значения ('raju', aes_encrypt ('kumar', 'key')) выберите *, приведите (aes_decrypt (пароль, 'ключ') как char (40)) из encrypt, где username = 'raju';

Пожалуйста, отформатируйте свой код и опишите, как он решает проблему.

ted 22.05.2018 15:25

Другие вопросы по теме