Подтвердить что ты не робот

Base64 кодируется в MySQL

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

4b9b3361

Ответ 1

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

Ответ 2

Функции из http://wi-fizzle.com/downloads/base64.sql содержат некоторую ошибку, когда в закодированной строке 32 байта (пробел), ex 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 ;

Ответ 3

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

Изменить: Или theres... this. Тьфу.

Ответ 4

Для тех, кого это интересует, это единственные альтернативы:

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 не заинтересована в ее реализации, поскольку эта функция уже существует на других языках, что кажется мне довольно глупым.

Ответ 5

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

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

Ответ 6

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

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