CREATE TABLE TEST_CHECKSUM
(
CORRECT_INPUT VARCHAR2(15),
CHECKSUM_ERR_INPUT VARCHAR2(1),
CHECKSUM_CORRECT VARCHAR2(1),
ERR_INPUT VARCHAR2(15),
TYPE VARCHAR2(10)
);
CREATE OR REPLACE PROCEDURE PopTestChks AS
i PLS_INTEGER;
corr_in PLS_INTEGER;
err_in PLS_INTEGER;
first_swap PLS_INTEGER;
second_swap PLS_INTEGER;
temp VARCHAR2(12);
BEGIN
DELETE FROM test_checksum;
FOR i IN 1 .. 5000 LOOP
corr_in := ROUND(DBMS_RANDOM.VALUE(1000, 1000000), 0);
--swap two random digits - make sure that the value for second is greater than first
--there is an easy opt here but I could not be bothered
<<try_again>>
first_swap := ROUND(DBMS_RANDOM.VALUE(1, LENGTH(corr_in)));
second_swap := ROUND(DBMS_RANDOM.VALUE(1, LENGTH(corr_in)));
IF second_swap <= first_swap THEN
GOTO try_again;
END IF;
temp :=
SUBSTR(corr_in, 1, first_swap - 1) || SUBSTR(corr_in, second_swap, 1)
|| SUBSTR(corr_in, first_swap + 1, second_swap - first_swap - 1) || SUBSTR(corr_in, first_swap, 1)
|| SUBSTR(corr_in, second_swap + 1, LENGTH(corr_in) - second_swap);
err_in := TO_NUMBER(temp);
INSERT INTO test_checksum t
(t.CORRECT_INPUT, t.ERR_INPUT, t.TYPE)
VALUES (corr_in, err_in, 'Any 2');
END LOOP;
--now do it again, but this time, just swap two consecutive digits
FOR i IN 1 .. 5000 LOOP
corr_in := ROUND(DBMS_RANDOM.VALUE(1000, 1000000), 0);
first_swap := ROUND(DBMS_RANDOM.VALUE(1, LENGTH(corr_in) - 1));
second_swap := first_swap + 1;
temp :=
SUBSTR(corr_in, 1, first_swap - 1) || SUBSTR(corr_in, second_swap, 1)
|| SUBSTR(corr_in, first_swap + 1, second_swap - first_swap - 1) || SUBSTR(corr_in, first_swap, 1)
|| SUBSTR(corr_in, second_swap + 1, LENGTH(corr_in) - second_swap);
err_in := TO_NUMBER(temp);
INSERT INTO test_checksum t
(t.CORRECT_INPUT, t.ERR_INPUT, t.TYPE)
VALUES (corr_in, err_in, 'Consec');
END LOOP;
UPDATE test_checksum t
SET t.CHECKSUM_CORRECT = chks(t.CORRECT_INPUT),
t.CHECKSUM_ERR_INPUT = chks(t.ERR_INPUT);
COMMIT;
END;
select count(1) from test_checksum t where t.CORRECT_INPUT != t.ERR_INPUT and t.CHECKSUM_CORRECT = t.CHECKSUM_ERR_INPUT and t.TYPE = 'Any 2'; --106
select count(1) from test_checksum t where t.CORRECT_INPUT = t.ERR_INPUT and t.TYPE = 'Any 2'; --493
select count(1) from test_checksum t where t.CORRECT_INPUT != t.ERR_INPUT and t.CHECKSUM_CORRECT = t.CHECKSUM_ERR_INPUT and t.TYPE = 'Consec'; --84
select count(1) from test_checksum t where t.CORRECT_INPUT = t.ERR_INPUT and t.TYPE = 'Consec'; --521