문제

한 테이블에서 Blob Col을 선택하고 Base64를 인코딩하여 다른 테이블에 삽입하고 싶습니다. DB와 내 앱을 통해 라운드를 트립하지 않고이 작업을 수행 할 수있는 방법이 있습니까?

도움이 되었습니까?

해결책

나는 같은 것을 찾고 있었고 MySQL 5.6 이이 기능을 지원하는 몇 가지 새로운 문자열 함수를 가지고 있음을 알았습니다. to_base64 그리고 From_base64.

다른 팁

기능 http://wi-fizzle.com/downloads/base64.sql 인코딩 된 문자열에서 32 바이트 (공간), ex base64_encode (cocat (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 ;
SELECT `id`,`name`, TO_BASE64(content) FROM `db`.`upload`

이것은 Blob 값을 변환합니다 콘텐츠 열에서 base64 문자열로. 그런 다음이 문자열로 다른 테이블에 삽입 할 수 있습니다.

그래도 아니요 요청되었습니다, 그리고 그것에 대한 UDF가 있습니다.

편집 : 또는 거기에… 이것. 어.

관심있는 사람들을 위해, 이것들은 지금까지 유일한 대안입니다.

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 개발 팀인 것 같습니다 구현에 관심이 없습니다 이 기능은 이미 다른 언어로 존재하기 때문에 나에게 꽤 어리석은 것 같습니다.

지원 테이블이 필요하지 않은 또 다른 사용자 정의 구현 :

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)

<5.6에 이것을 필요로한다면, 나는이 UDF를 가로 질러 트렸다.

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

테이블 암호화 생성 (Username Varchar (20), Password Varbinary (200))

암호화 값 ( 'raju', aes_encrypt ( 'kumar', 'key'))에 삽입 *, username = 'raju'에서 암호화에서 *, cast (aes_decrypt (암호, '키'));

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top