Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Edgars.

Asked: April 11, 2002 - 11:40 am UTC

Last updated: February 15, 2006 - 2:13 pm UTC

Version: 9.0.1.3

Viewed 10K+ times! This question is

You Asked

Hello Tom!

I have few questions:

1. Can I do left/right binary shift on RAW datatypes?

2. Is there a built in function or something like this to implement CRC32/CRC16 on RAW data? I was trying to write Java Package, but because I have little experience in Java I had no luck. For now my CRC32 implementation uses TABLE that I generated in C with CRC values and PL/SQL function that does byte searching in this table and lookups crc32 using known algorithm. Maybe this can be done easily?

3. Where can I find some info on DBMS_JAVA package, I was searching in Oracle Documentation, but I didn't finded normal description of it. When I try to create and compile java source named "something" I get java.security.AccessControlException.

Thank you!


and Tom said...

1) 8 bits at a time - with utl_raw.substr. otherwise, we really don't have a "bit shift". we could work something out in a java stored procedure pretty easily I'm sure.

2) how about an MD5 checksum -- would that work? dbms_obfuscation_toolkit has just such a thing. Not a CRC but a checksum none the less.

3) If you have my book -- i've pulled it all together in the appendix section on dbms_java. Else it is in the "Java Developers Guide"

</code> http://www.oracle.com/pls/db901/db901.to_toc?pathname=java.901/a90209/config.htm#1009372 <code>



Rating

  (4 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Meaning of CRC, MD5?

A reader, April 11, 2002 - 2:48 pm UTC

What do CRC, CRC32 and MD5 stand for?



Tom Kyte
April 11, 2002 - 7:09 pm UTC

</code> http://www.acronymfinder.com/ <code>

is a great place.

CRC is the Cyclic Redundancy Code (lots of hits on that). It's a way to "validate" data -- modems use it lots to make sure that what comes out is what came in.

MD5 is Message Digest 5 - it's a one way hash that can be used to verify that the document you recieve is the one that was sent for example -- these two things serve similar purposes.

stands foe

Jim Kennedy, April 11, 2002 - 3:44 pm UTC

CRC - cyclical reduncancy check
crc32 - cyclical reduncancy check 32 ( more accurate for large things)
MD5 - message digest (I think)

Bitshift pl/sql

Evan Benoit, September 15, 2004 - 9:15 am UTC

There's a workaround in pl/sql. A bitshift is logically the same as multiplying or dividing by a power of 2. So, you just need to convert the raw to a number, do the operation, and convert back to raw. The following PL/SQL seems to work well:

function bitShiftLeft(i_raw in raw, i_bits in number) return raw is
begin
return utl_raw.cast_from_binary_integer(utl_raw.cast_to_binary_integer(i_raw) * (2**i_bits));
end;

function bitShiftRight(i_raw in raw, i_bits in number) return raw is
begin
return utl_raw.cast_from_binary_integer(floor(utl_raw.cast_to_binary_integer(i_raw) / (2**i_bits)));
end;

Note a few things:
1) This won't really work well for large raws (more than a few bytes), since the number will get too large
2) This probably isn't as fast as a true c-style bitshift. I'm not really sure what oracle does internally to handle this operation, it might not be pretty
3) Both operations seem to left-pad the response with 0's, up to 4 bytes. Not sure why that is. That might pose a problem, depending on your application.

CRC

Su Baba, February 15, 2006 - 1:48 pm UTC

Can I use outln_edit_pkg.generate_signature API to implement CRC?

I had read it somewhere that in a data warehouse environment where you want to detect changes between the source and target environments, using CRC to do the comparison can increase the speed by up to 10 fold.

I've created a simple test case below to simulate this. However, the comparison using CRC is actually slower. Am I using it the way it is supposed to be used? Thanks.

By the way, I've run each of the SQL statements multiple times and the result is pretty much the same each time.

-- ----------------------------------------------------------------------
-- Imitating a CRC algorithm
-- ----------------------------------------------------------------------
CREATE OR REPLACE FUNCTION f_get_sign (p_text VARCHAR2)
RETURN RAW
DETERMINISTIC
AS
l_signature RAW(32);
l_text2 VARCHAR2(32767);

BEGIN
l_text2 := p_text;

IF l_text2 IS NULL THEN
l_text2 := '1';
END IF;

sys.outln_edit_pkg.generate_signature(l_text2, l_signature);
RETURN l_signature;
END;
/

-- ----------------------------------------------------------------------
-- Create a reasonably "large" table.
-- ----------------------------------------------------------------------
DROP TABLE x;

CREATE TABLE x NOLOGGING AS
SELECT object_id, owner, object_name, subobject_name, object_type,
f_get_sign(owner || object_name ||
subobject_name || object_type) crc_signature
FROM all_objects;

ALTER TABLE x ADD PRIMARY KEY (object_id);

ANALYZE TABLE x COMPUTE STATISTICS;

SELECT COUNT(*) FROM x;

COUNT(*)
----------
40705


-- ----------------------------------------------------------------------
-- Straight comparison
-- ----------------------------------------------------------------------
set time on
set timing on

SELECT COUNT(*), change_indicator
FROM (
SELECT (CASE WHEN a.owner <> x.owner OR
a.object_name <> x.object_name OR
a.subobject_name <> x.subobject_name OR
a.object_type <> x.object_type
THEN 'MODIFIED'
ELSE 'INTACT'
END) change_Indicator
FROM all_objects a, x
WHERE a.object_id = x.object_id
)
GROUP BY change_indicator;

COUNT(*) CHANGE_I
---------- --------
40705 INTACT

Elapsed: 00:00:03.04

-- ----------------------------------------------------------------------
-- Using CRC algorithm
-- ----------------------------------------------------------------------
SELECT COUNT(*), change_indicator
FROM (
SELECT (CASE WHEN f_get_sign(a.owner || a.object_name ||
a.subobject_name || a.object_type) =
x.crc_signature
THEN 'INTACT'
ELSE 'MODIFIED'
END) change_Indicator
FROM all_objects a, x
WHERE a.object_id = x.object_id
)
GROUP BY change_indicator;

COUNT(*) CHANGE_I
---------- --------
40705 INTACT

Elapsed: 00:00:05.00

set time off
set timing off




Tom Kyte
February 15, 2006 - 2:13 pm UTC

... using CRC to do the
comparison can increase the speed by up to 10 fold. ...

it can increase a table compare by lots more, or lots less than that. Don't know why someone would pick "10" - semi random number.

Oracle 10g, use ora_hash on the concatenation of the columns and sum it up. Get the sum of the hashes of the rows.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library