Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

After some code to convert from 8bits to 6bits to 8bits 1

Status
Not open for further replies.

MikeJones

Programmer
Nov 1, 2000
259
GB
Hi all,

I'm not really a Java programmer so can you all please go easy on me, I'm afraid I'm one of those hated Oracle developers... As part of Oracle 8i you can now imbed Java straight into the DB which is great as the native language that comes with Oracle is to say the least, DB orientated.

Anyway back to the point of this post...

I'm looking for a bit of code that will take 3 8-bit bytes then internally convert them to 4 6-bit bytes. Then pad (right pad with 0) each of the 6-bit bytes to 8-bit bytes and return these 4 8-bit bytes.
So overall the Java would recieve 3 8-bit bytes and return 4 8-bit bytes.

I can then hopefullt compile this into Oracle and volia!

Does anyone have such code??


Cheers,

Mike.
 
Hi,

Try this code :

public class Foo
{

public static byte[] shiftBytes (byte b1, byte b2, byte b3)
{
byte[] res = new byte[4];

res[0] = (byte) ((b1 & 0xCF) + (b2 & 0x3F) + (b3 & 0x0C));
res[1] = (byte) (b1 << 2);
res[2] = (byte) (b2 << 2);
res[3] = (byte) (b3 << 2);
return res;
}

public static void main (String[] args)
{
byte[] array = shiftBytes ((byte) 4, (byte) 6, (byte) 12);

for (int i = 0; i < array.length; i++)
System.out.println (array);
}
}

And tell me if it does what you want.

Bye --
Globos
 
Another solution is more like the UUEncode byte shifting.

public byte[] shiftBytes(byte b1, byte b2, byte b3)
{
byte[] b = new byte[4];
b[0] = (byte)((b1 & 0xFC)>>2);
b[1] = (byte)(((b1 & 0x03) <<4) | (b2 & 0xF0));
b[2] = (byte)(((b2 & 0x0F) <<2) | (b3 & 0xC0));
b[3] = (byte)(b3 & 0x3F);

return b;
}

Greetings,
Steven.
 
Cheers Java people, to be honest the UUencode byte shift is exactly what I am trying to achieve. I figure it would be quite nice if Oracle could UUencode it'self rather than having to pipe files out to it's O/S and then get them back UUEncoded. Any body got an algorithim to do Base64 while I'm at it?!? I could write a mail client in Oracle!

Cheers,

Mike.
 
I'm not taking credit for this code because i've found it somewhere on the web. (Unfortunately i don't know the original author). But here is the Base64 encoding/decoding algorithm.

static private byte[] codes = new byte[256];
static {
for (int i=0; i<256; i++) codes = -1;
for (int i = 'A'; i <= 'Z'; i++) codes = (byte)( i - 'A');
for (int i = 'a'; i <= 'z'; i++) codes = (byte)(26 + i - 'a');
for (int i = '0'; i <= '9'; i++) codes = (byte)(52 + i - '0');
codes['+'] = 62;
codes['/'] = 63;
}

private byte[] decode(String data) { return decode(data.toCharArray()); }
private byte[] decode(char[] data)
{
// as our input could contain non-BASE64 data (newlines,
// whitespace of any sort, whatever) we must first adjust
// our count of USABLE data so that...
// (a) we don't misallocate the output array, and
// (b) think that we miscalculated our data length
// just because of extraneous throw-away junk

int tempLen = data.length;
for( int ix=0; ix<data.length; ix++ )
{
if( (data[ix] > 255) || codes[ data[ix] ] < 0 )
--tempLen; // ignore non-valid chars and padding
}
// calculate required length:
// -- 3 bytes for every 4 valid base64 chars
// -- plus 2 bytes if there are 3 extra base64 chars,
// or plus 1 byte if there are 2 extra.

int len = (tempLen / 4) * 3;
if ((tempLen % 4) == 3) len += 2;
if ((tempLen % 4) == 2) len += 1;

byte[] out = new byte[len];



int shift = 0; // # of excess bits stored in accum
int accum = 0; // excess bits
int index = 0;

// we now go through the entire array (NOT using the 'tempLen' value)
for (int ix=0; ix<data.length; ix++)
{
int value = (data[ix]>255)? -1: codes[ data[ix] ];

if ( value >= 0 ) // skip over non-code
{
accum <<= 6; // bits shift up by 6 each time thru
shift += 6; // loop, with new bits being put in
accum |= value; // at the bottom.
if ( shift >= 8 ) // whenever there are 8 or more shifted in,
{
shift -= 8; // write them out (from the top, leaving any
out[index++] = // excess at the bottom for next iteration.
(byte) ((accum >> shift) & 0xff);
}
}
// we will also have skipped processing a padding null byte ('=') here;
// these are used ONLY for padding to an even length and do not legally
// occur as encoded data. for this reason we can ignore the fact that
// no index++ operation occurs in that special case: the out[] array is
// initialized to all-zero bytes to start with and that works to our
// advantage in this combination.
}

// if there is STILL something wrong we just have to throw up now!
if( index != out.length)
{
throw new Error(&quot;Miscalculated data length (wrote &quot; + index + &quot; instead of &quot; + out.length + &quot;)&quot;);
}

return out;
}

static private char[] alphabet =
&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=&quot;
.toCharArray();

private char[] encode(String data) { return encode(data.getBytes()); }
private char[] encode(byte[] data)
{

char[] out = new char[((data.length + 2) / 3) * 4];

//
// 3 bytes encode to 4 chars. Output is always an even
// multiple of 4 characters.
//
for (int i=0, index=0; i<data.length; i+=3, index+=4) {
boolean quad = false;
boolean trip = false;

int val = (0xFF & (int) data);
val <<= 8;
if ((i+1) < data.length) {
val |= (0xFF & (int) data[i+1]);
trip = true;
}
val <<= 8;
if ((i+2) < data.length) {
val |= (0xFF & (int) data[i+2]);
quad = true;
}
out[index+3] = alphabet[(quad? (val & 0x3F): 64)];
val >>= 6;
out[index+2] = alphabet[(trip? (val & 0x3F): 64)];
val >>= 6;
out[index+1] = alphabet[val & 0x3F];
val >>= 6;
out[index+0] = alphabet[val & 0x3F];
}
return out;
}

Greetings,
Steven.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top