utl_encode imagen decodificar btoa atob oracle base64

oracle - imagen - Codificación y decodificación Base64 en oráculo



decodificar imagen base64 javascript (4)

¿Cómo puedo hacer que Base64 codifique / decodifique un valor en Oracle?


Implementé esto para enviar correos cirílicos a través de mi servidor de MS Exchange.

function to_base64(t in varchar2) return varchar2 is begin return utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(t))); end to_base64;

Intentalo.

upd: después de un pequeño ajuste, se me ocurrió esto, así que funciona en ambos sentidos ahora:

function from_base64(t in varchar2) return varchar2 is begin return utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw(t))); end from_base64;

Usted puede comprobarlo:

SQL> set serveroutput on SQL> SQL> declare 2 function to_base64(t in varchar2) return varchar2 is 3 begin 4 return utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(t))); 5 end to_base64; 6 7 function from_base64(t in varchar2) return varchar2 is 8 begin 9 return utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw (t))); 10 end from_base64; 11 12 begin 13 dbms_output.put_line(from_base64(to_base64(''asdf''))); 14 end; 15 / asdf PL/SQL procedure successfully completed

upd2: Ok, aquí hay una conversión de muestra que funciona para CLOB . Solo se me ocurrió. Trata de resolverlo para tus blobs. :)

declare clobOriginal clob; clobInBase64 clob; substring varchar2(2000); n pls_integer := 0; substring_length pls_integer := 2000; function to_base64(t in varchar2) return varchar2 is begin return utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(t))); end to_base64; function from_base64(t in varchar2) return varchar2 is begin return utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw(t))); end from_base64; begin select clobField into clobOriginal from clobTable where id = 1; while true loop /*we substract pieces of substring_length*/ substring := dbms_lob.substr(clobOriginal, least(substring_length, substring_length * n + 1 - length(clobOriginal)), substring_length * n + 1); /*if no substring is found - then we''ve reached the end of blob*/ if substring is null then exit; end if; /*convert them to base64 encoding and stack it in new clob vadriable*/ clobInBase64 := clobInBase64 || to_base64(substring); n := n + 1; end loop; n := 0; clobOriginal := null; /*then we do the very same thing backwards - decode base64*/ while true loop substring := dbms_lob.substr(clobInBase64, least(substring_length, substring_length * n + 1 - length(clobInBase64)), substring_length * n + 1); if substring is null then exit; end if; clobOriginal := clobOriginal || from_base64(substring); n := n + 1; end loop; /*and insert the data in our sample table - to ensure it''s the same*/ insert into clobTable (id, anotherClobField) values (1, clobOriginal); end;


La solución con utl_encode.base64_encode y utl_encode.base64_decode tiene una limitación, solo funcionan con cadenas de hasta 32.767 caracteres / bytes.

En caso de que tengas que convertir cuerdas más grandes, enfrentarás varios obstáculos.

  • Para BASE64_ENCODE la función tiene que leer 3 Bytes y transformarlos. En el caso de caracteres Multi-Byte (por ejemplo, öäüè€ almacenado en UTF-8, también conocido como AL32UTF8 ) 3 Character no son necesariamente también 3 Bytes . Para leer siempre 3 Bytes, primero debe convertir su CLOB en BLOB .
  • El mismo problema se aplica para BASE64_DECODE . La función tiene que leer 4 bytes y transformarlos en 3 bytes. Esos 3 bytes no son necesariamente también 3 caracteres
  • Normalmente, un BASE64-String tiene caracteres NEW_LINE ( CR y / o LF ) cada 64 caracteres. Dichos caracteres de nueva línea deben ignorarse durante la decodificación.

Tomando todo esto en consideración, la solución completa podría ser esta:

CREATE OR REPLACE FUNCTION DecodeBASE64(InBase64Char IN OUT NOCOPY CLOB) RETURN CLOB IS blob_loc BLOB; clob_trim CLOB; res CLOB; lang_context INTEGER := DBMS_LOB.DEFAULT_LANG_CTX; dest_offset INTEGER := 1; src_offset INTEGER := 1; read_offset INTEGER := 1; warning INTEGER; ClobLen INTEGER := DBMS_LOB.GETLENGTH(InBase64Char); amount INTEGER := 1440; -- must be a whole multiple of 4 buffer RAW(1440); stringBuffer VARCHAR2(1440); -- BASE64 characters are always simple ASCII. Thus you get never any Mulit-Byte character and having the same size as ''amount'' is sufficient BEGIN IF InBase64Char IS NULL OR NVL(ClobLen, 0) = 0 THEN RETURN NULL; ELSIF ClobLen<= 32000 THEN RETURN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(InBase64Char))); END IF; -- UTL_ENCODE.BASE64_DECODE is limited to 32k, process in chunks if bigger -- Remove all NEW_LINE from base64 string ClobLen := DBMS_LOB.GETLENGTH(InBase64Char); DBMS_LOB.CREATETEMPORARY(clob_trim, TRUE); LOOP EXIT WHEN read_offset > ClobLen; stringBuffer := REPLACE(REPLACE(DBMS_LOB.SUBSTR(InBase64Char, amount, read_offset), CHR(13), NULL), CHR(10), NULL); DBMS_LOB.WRITEAPPEND(clob_trim, LENGTH(stringBuffer), stringBuffer); read_offset := read_offset + amount; END LOOP; read_offset := 1; ClobLen := DBMS_LOB.GETLENGTH(clob_trim); DBMS_LOB.CREATETEMPORARY(blob_loc, TRUE); LOOP EXIT WHEN read_offset > ClobLen; buffer := UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(DBMS_LOB.SUBSTR(clob_trim, amount, read_offset))); DBMS_LOB.WRITEAPPEND(blob_loc, DBMS_LOB.GETLENGTH(buffer), buffer); read_offset := read_offset + amount; END LOOP; DBMS_LOB.CREATETEMPORARY(res, TRUE); DBMS_LOB.CONVERTTOCLOB(res, blob_loc, DBMS_LOB.LOBMAXSIZE, dest_offset, src_offset, DBMS_LOB.DEFAULT_CSID, lang_context, warning); DBMS_LOB.FREETEMPORARY(blob_loc); DBMS_LOB.FREETEMPORARY(clob_trim); RETURN res; END DecodeBASE64; CREATE OR REPLACE FUNCTION EncodeBASE64(InClearChar IN OUT NOCOPY CLOB) RETURN CLOB IS dest_lob BLOB; lang_context INTEGER := DBMS_LOB.DEFAULT_LANG_CTX; dest_offset INTEGER := 1; src_offset INTEGER := 1; read_offset INTEGER := 1; warning INTEGER; ClobLen INTEGER := DBMS_LOB.GETLENGTH(InClearChar); amount INTEGER := 1440; -- must be a whole multiple of 3 -- size of a whole multiple of 48 is beneficial to get NEW_LINE after each 64 characters buffer RAW(1440); res CLOB := EMPTY_CLOB(); BEGIN IF InClearChar IS NULL OR NVL(ClobLen, 0) = 0 THEN RETURN NULL; ELSIF ClobLen <= 24000 THEN RETURN UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(InClearChar))); END IF; -- UTL_ENCODE.BASE64_ENCODE is limited to 32k/(3/4), process in chunks if bigger DBMS_LOB.CREATETEMPORARY(dest_lob, TRUE); DBMS_LOB.CONVERTTOBLOB(dest_lob, InClearChar, DBMS_LOB.LOBMAXSIZE, dest_offset, src_offset, DBMS_LOB.DEFAULT_CSID, lang_context, warning); LOOP EXIT WHEN read_offset >= dest_offset; DBMS_LOB.READ(dest_lob, amount, read_offset, buffer); res := res || UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(buffer)); read_offset := read_offset + amount; END LOOP; DBMS_LOB.FREETEMPORARY(dest_lob); RETURN res; END EncodeBASE64;


Todas las publicaciones anteriores son correctas. Hay más de una manera de despellejar a un gato. Aquí hay otra forma de hacer lo mismo: (simplemente reemplace "what_ever_you_want_to_convert" con su cadena y ejecútelo en Oracle:

set serveroutput on; DECLARE v_str VARCHAR2(1000); BEGIN --Create encoded value v_str := utl_encode.text_encode (''what_ever_you_want_to_convert'',''WE8ISO8859P1'', UTL_ENCODE.BASE64); dbms_output.put_line(v_str); --Decode the value.. v_str := utl_encode.text_decode (v_str,''WE8ISO8859P1'', UTL_ENCODE.BASE64); dbms_output.put_line(v_str); END; /

source


do url_raw.cast_to_raw() soporte en oráculo 6