¿Cómo puedo hacer que Base64 codifique/descodifique un valor en Oracle?Codificación y decodificación Base64 en Oracle
Respuesta
He implementado esto para enviar correos electrónicos a través cirílico mi servidor 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;
Pruébalo.
UPD: después de un ajuste menor que se me ocurrió esto, por lo 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;
se puede comprobar:
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;
http://psoug.org/reference/utl_encode.html cheque dos primeros
puede u por favor dígame cómo hacerlo para el tipo de datos BLOB? Obtengo una excepción "Bugger Too small para CLOB to CHAR o BLOB to RAW conversion (real 50176, maximum 2000)". – Pradeep
Lo siento ... Recibo una excepción "BufferToo pequeño para conversión CLOB a CHAR o BLOB a RAW (50176 reales, máximo 2000)". – Pradeep
oracle utl_raw package acepta solo entrada varchar2, que es corta, así que supongo que todo lo que puedes hacer al respecto es dividir tu blob en fragmentos más pequeños utilizando el paquete dbms_lob, luego convertir cada uno de ellos usando el método que proporcioné y luego volver a unirlos en una sola burbuja. ¿puede dar un código de error que está recibiendo, por cierto? –
Todas las publicaciones anteriores son correctas. Hay más de una manera de despellejar a un gato. Aquí hay otra manera de hacer la misma cosa: (basta con sustituir "what_ever_you_want_to_convert" con su cadena y ejecutarlo 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;
/
hacer url_raw.cast_to_raw()
apoyo en el oráculo 6
solución con utl_encode.base64_encode
y utl_encode.base64_decode
tienen una limitación, funcionan solo con cadenas de hasta 32.767 caracteres/bytes.
En caso de que tenga que convertir cadenas más grandes se encontrará con varias o bstá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 comoAL32UTF8
) 3 Carácter no son necesariamente también 3 Bytes. Para leer siempre 3 Bytes primero debe convertir suCLOB
enBLOB
. - El mismo problema se aplica al
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 NEW_LINE (
CR
y/oLF
) carácter cada 64 caracteres. Dichos caracteres de nueva línea deben ignorarse durante la decodificación.
Tomando todo esto en consideración la completa solución podría ser ésta:
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;
- 1. JSON de codificación/decodificación de codificación base64/decodificación en JavaScript
- 2. Decodificación Base64 Imágenes
- 3. Decodificación Base64 Imagen
- 4. MD5 codificación Hash y Base64
- 5. codificación base64 en MySQL
- 6. Decodificación de una cadena Base64 en Java
- 7. Node.js Base64 Decodificación de imagen y escritura en el archivo
- 8. iPhone - codificación y decodificación de una NSValue
- 9. Byte de codificación y decodificación [] con ZXing
- 10. La decodificación de Base64 con JDK6 solo
- 11. Imagen de codificación Base64
- 12. ¿Detecta codificación base64 en PHP?
- 13. Codificación Base64 en Java/Groovy
- 14. Detectar codificación base64
- 15. Django urlsafe decodificación base64 con descifrado
- 16. Codificación/decodificación URL con Python
- 17. Unicode Problemas de codificación y decodificación en QRCode
- 18. base64 codificación cadenas unicode en python 2.7
- 19. Encriptar y desencriptar con codificación AES y Base64
- 20. PHP: HTML Codificación de atributo/JavaScript Decodificación
- 21. Hibernate Oracle y codificación de caracteres
- 22. codificación Base64 excepción utilizando impulso tiro
- 23. UIImage a base64 Codificación de cadena
- 24. ¿Cómo convertir una imagen a codificación base64?
- 25. Comparación de fechas en Oracle utilizando la función de decodificación
- 26. Decodificación Base32
- 27. Oracle SQL Developer Environment codificación
- 28. Unicode y `decodificación()` en Python
- 29. Node.JS - Codificación de imágenes en base64 usando el Buffer
- 30. ¿Por qué el relleno se usa en la codificación Base64?
me funciona bastante bien, aunque tengo espacios en medio de mi codificación. Puse un espacio de expresión regular reemplazar alrededor de mi resultado y estoy en el negocio: regexp_replace (utl_raw.cast_to_varchar2 (utl_encode.base64_encode (utl_raw.cast_to_raw (t))), '[[: espacio:]] *', '') – Kirby
Hay un pequeño error en su segunda actualización: el parámetro "amount" de dbms_log.substr debe ser "least (substring_length, length (clobInBase64) - (substring_length * n + 1))". La forma en que lo escribió arroja una cantidad negativa, por lo que la subcadena siempre está vacía. – BernardMarx
La codificación BASE64 toma 3 bytes de flujo de entrada y lo convierte en 4 * 3 bytes. Cada uno de estos 3 bytes se asigna a 64 caracteres diferentes (a-z, A-Z, 0-9, "+", "/", por lo que se obtiene el nombre BASE64). Asegúrese de que el valor de substring_length sea un múltiplo entero de 4 para 'BASE64_DECODE', resp. un múltiplo entero de 3 para 'BASE64_ENCODE'. Por lo tanto, su función 'to_base64' puede devolver resultados incorrectos. –