Codificación base64 en MySQL

Quiero seleccionar un blob col de una tabla, base64 codificarlo e insertarlo en otras tablas. ¿Hay alguna forma de hacerlo sin tener que pasar los datos de la base de datos y de mi aplicación?

Estaba buscando lo mismo y acabo de ver que MySQL 5.6 tiene un par de nuevas funciones de cadena que soportan esta funcionalidad: TO_BASE64 y FROM_BASE64 .

Las funciones de http://wi-fizzle.com/downloads/base64.sql contienen algunos errores cuando en la cadena codificada son 32 bytes (espacio), ex BASE64_ENCODE (CONCAT (CHAR (15), CHAR (32))). Aquí está la función corregida

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 ; 

Parece que no, aunque se solicitó , y hay un UDF para eso.

Editar: O hay … esto . Ugh.

Para los interesados, estas son las únicas alternativas hasta el momento:

1) Usando estas funciones:

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

2) Si ya tiene el UDF sys_eval , (Linux) puede hacer esto:

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

Se sabe que el primer método es lento. El problema con el segundo, es que la encoding realmente está ocurriendo “fuera” de MySQL, que puede tener problemas de encoding (además de los riesgos de seguridad que está agregando con las funciones sys_ *).

Lamentablemente, no existe una versión comstackda de UDF (que debería ser más rápida) ni una compatibilidad nativa en MySQL (¡ Posgresql lo admite !).

Parece que el equipo de desarrollo de MySQL no está interesado en implementarlo, ya que esta función ya existe en otros idiomas, lo cual me parece bastante tonto.

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

esto convertirá el valor de blob de la columna de contenido a la cadena de base64. Entonces puedes hacer con esta cadena lo que quieras incluso insertarlo en otra mesa

Si necesita esto para <5.6, tropecé con esta UDF que parece funcionar bien:

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

Sin embargo, otra implementación personalizada que no requiere tabla de soporte:

 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; 

Esencia

Debe convertir el juego de caracteres después de la deencoding: convert(base64_decode(base64_encode('ёлка')) using utf8)

create table encrypt (nombre de usuario varchar (20), contraseña varbinary (200))

insertar en valores cifrados (‘raju’, aes_encrypt (‘kumar’, ‘clave’)) seleccione *, cast (aes_decrypt (contraseña, ‘clave’) como char (40)) de encrypt where username = ‘raju’;