3

Click here to load reader

10g Base64 Encoding

  • Upload
    nikochu

  • View
    116

  • Download
    2

Embed Size (px)

Citation preview

Page 1: 10g Base64 Encoding

10g Base64 Encoding/DecodingAsked by hsnl_support in Oracle 10.x

Tags: Oracle, Base64, Encoding, Decoding, Lobs

Hi,

I have a range of documents, mainly pdf and word documents stored in a table as a blob. I need to output this blob in XML as base64 encoded data.  

I have written a procedure to select the blob from a table, read a chunk of the blob, encode the raw data with utl_encode.base64_encode, convert this to a string and then append it to a clob.  The clob is then stored in a table for easy retrieval for xml output.

I then read the clob from the table, read a chunk of the clob, convert the character data back to the raw format, decode the raw data using utl_encode.base64_decode and then append this to a blob.  The blob is then stored back in a table so it can be opened.

The problem I encounter is that the blob I have decoded is different at the binary level and does not open properly.  I have used SQL Detective to compare the original blobs binary code to the encoded/decoded blobs binary code.  I have searched the internet and found a bizarre post that suggests the base64 encoding utility prefers chunks of data that are a multiple of 48 rather than 64.  I have successfully encoded and decoded a 3kb pdf file using a chunk size of 1080, however if I use a chunk size of 1024 it does not work.  I tired the exact same size on a 29kb file and found it did not work, however with the file size being approx 10x larger I decided to try a 10x larger chunk size of 10080, this worked fine.  Neither of the above methods work on a 20kb word document which I find bizarre.  

Can anyone help me work out a solution to this problem, is there something fundamental I am missing?  The code I am using is below, its quite rough but does work.

Page 2: 10g Base64 Encoding

set serveroutput on declare  l_enc_str     varchar2(32767);   l_clob        clob;  l_blob        blob;  l_blob2       blob;  buffer        raw(32767);  l_len         number;  l_chunk       varchar2(16000);  l_offset      number := 1;  l_chunk_len   number;  l_raw         raw(32767);  l_decoded_raw raw(16000);begin    dbms_lob.createtemporary(l_clob, true);  dbms_lob.createtemporary(l_blob, true);    --Encode blob and store as clob.  select doc_blob into l_blob from doc_lob where doc_id = 33539;     l_len :=dbms_lob.getlength(l_blob);  while l_offset < l_len   loop    if (l_len - l_offset) < 10080 then          l_chunk_len := (l_len-l_offset);        else          l_chunk_len := 10080;    end if;    dbms_lob.read(l_blob, l_chunk_len, l_offset, buffer);    l_raw:=utl_encode.base64_encode(buffer);    l_enc_str := utl_raw.cast_to_varchar2(l_raw);    dbms_lob.append(l_clob, l_enc_str);    l_offset := l_offset + l_chunk_len;   end loop;  insert into wd_temp_clob_blob (doc_clob) values (l_clob);    dbms_lob.freetemporary(l_clob);  dbms_lob.createtemporary(l_clob, true);   --Decode clode and store as blob  select doc_clob into l_clob from wd_temp_clob_blob;  l_len := dbms_lob.getlength(l_clob);  l_offset:=1;    dbms_lob.createtemporary(l_blob2, true);  while l_offset < l_len   loop    if (l_len - l_offset) < 10080then          l_chunk_len := (l_len-l_offset);        else          l_chunk_len := 10080;    end if;

Page 3: 10g Base64 Encoding

    l_enc_str := dbms_lob.substr(l_clob,l_chunk_len,l_offset);    l_raw:= utl_raw.cast_to_raw(l_enc_str);    buffer:= utl_encode.base64_decode(l_raw);    dbms_lob.append(l_blob2, buffer);    l_offset := l_offset + l_chunk_len;   end loop;    insert into wd_temp_clob_blob (dob_bloc) values (l_blob2); end;/