Good News Everybody!
The new search engine is LIVE!
Please report any problems to david (at) midrange.com.
|
From: Dan Bale <dbale@samsa.com>
> Thanks for the offer. Basically, I want to call this program giving it
> parameters Library, File, & Member for input, and getting back the hash
> value as a parameter. Maybe another parameter for a Return Code / Error
> MsgID. The program SHOULD IGNORE the first 12 bytes of the source record
> (the date & sequence number), and use only positions 13 through the record
> length to calculate the hash. Note that I am hoping that record length
> doesn't matter; i.e., the goal is that generating identical hash values for
> two source members that are identical in content but have different record
> lengths.
>
> Example call:
>
> c Call 'MIFHASH'
> c Parm Library 10 input
> c Parm File 10 input
> c Parm Member 10 input
> c Parm HashValue 40 output
>
Dan,
I'm also sending the program to you by private email.
Below is basically what you want. The last parameter (the hash)
you had specified as 40 bytes long. The SHA-1 hash is 20 bytes
of binary data. I convert that into the equivalent 40 bytes of printable
hex data e.g. "F122C3..." You can change that to suit.
Here goes:
DCL SPCPTR .ODP;
DCL SPC ODP BAS(.ODP);
DCL DD ODP.DCB BIN(4) DEF(ODP) POS(17);
DCL SPCPTR .OPEN-FEEDBACK;
DCL SPC OPEN-FEEDBACK BAS(.OPEN-FEEDBACK);
DCL DD OPEN-RECORD-LENGTH BIN(2) DEF(OPEN-FEEDBACK) POS(45);
DCL SPCPTR .DCB;
DCL SPC DCB BAS(.DCB);
DCL DD DCB-GET BIN(2) DEF (DCB) POS(25);
DCL SPCPTR .NULL;
DCL SPCPTR @SEPT BASPCO;
DCL SYSPTR .SEPT(6440) BAS(@SEPT);
DCL CON CLOSE-ENTRY BIN(2) INIT(11);
DCL CON OPEN-ENTRY BIN(2) INIT(12);
DCL SPCPTR .IFCB INIT(IFCB);
DCL DD IFCB CHAR(211) BDRY(16);
DCL SPCPTR .IFCB-ODP DEF(IFCB) POS( 1);
DCL SPCPTR .IFCB-INBUF DEF(IFCB) POS( 17);
DCL SPCPTR .IFCB-OPEN-FEEDBACK DEF(IFCB) POS( 49);
DCL DD IFCB-FILE CHAR(10) DEF(IFCB) POS(129);
DCL DD IFCB-LIB-ID BIN(2) DEF(IFCB) POS(139) INIT(72);
DCL DD IFCB-LIBRARY CHAR(10) DEF(IFCB) POS(141);
DCL DD IFCB-MBR-ID BIN(2) DEF(IFCB) POS(151) INIT(73);
DCL DD IFCB-MEMBER CHAR(10) DEF(IFCB) POS(153);
DCL DD IFCB-FLAGS-1 CHAR(1) DEF(IFCB) POS(175) INIT(X'80');
DCL DD IFCB-FLAGS-2 CHAR(1) DEF(IFCB) POS(176) INIT(X'20');
DCL DD IFCB-NO-MORE-PARMS BIN (2) DEF(IFCB) POS(209) INIT(32767);
DCL OL OPEN-I(.IFCB);
DCL OL CLOSE-I(.IFCB);
DCL DD GET-ENTRY BIN(2);
DCL DD INBUF CHAR(268) BAS(.IFCB-INBUF);
DCL DD GET-OPTION BIN(4) INIT(H'03000001');
DCL SPCPTR .GET-OPTION INIT(GET-OPTION);
DCL OL GET-OPERATION(.IFCB, .GET-OPTION, .NULL);
DCL EXCM * EXCID(H'5001') BP(EOF-DETECTED) CV("CPF") IMD;
DCL DD CONTROL CHAR(32) BDRY(16);
DCL DD CTRL-FUNCTION CHAR(2) DEF(CONTROL) POS( 1);
DCL DD CTRL-ALGORITHM CHAR(1) DEF(CONTROL) POS( 3);
DCL DD CTRL-SEQUENCE CHAR(1) DEF(CONTROL) POS( 4);
DCL DD CTRL-LENGTH BIN(4) DEF(CONTROL) POS( 5);
DCL DD * CHAR(8) DEF(CONTROL) POS( 9);
DCL SPCPTR .WORK DEF(CONTROL) POS(17);
DCL DD WORK CHAR(96); /* PRIVATE WORK AREA FOR CIPHER */
DCL SPCPTR .CIPHER-RESULT INIT(CIPHER-RESULT);
DCL DD CIPHER-RESULT CHAR(20);
DCL SPCPTR .CIPHER-SOURCE INIT(CIPHER-SOURCE);
DCL DD CIPHER-SOURCE CHAR(257);
DCL DD TEXT-LENGTH BIN(2);
DCL SPCPTR .PARM1 PARM;
DCL DD PARM-LIBRARY CHAR(10) BAS(.PARM1);
DCL SPCPTR .PARM2 PARM;
DCL DD PARM-FILE CHAR(10) BAS(.PARM2);
DCL SPCPTR .PARM3 PARM;
DCL DD PARM-MEMBER CHAR(10) BAS(.PARM3);
DCL SPCPTR .PARM4 PARM;
DCL DD PARM-HASH CHAR(40) BAS(.PARM4);
DCL OL PARMS(.PARM1, .PARM2, .PARM3, .PARM4) PARM EXT MIN(4);
/**************************************************************/
ENTRY * (PARMS) EXT;
OPEN-INPUT-FILE:
CPYBLA IFCB-LIBRARY, PARM-LIBRARY;
CPYBLA IFCB-FILE, PARM-FILE ;
CPYBLA IFCB-MEMBER, PARM-MEMBER ;
CALLX .SEPT(OPEN-ENTRY), OPEN-I, *;
CPYBWP .OPEN-FEEDBACK, .IFCB-OPEN-FEEDBACK;
SUBN TEXT-LENGTH, OPEN-RECORD-LENGTH, 12;
CPYBWP .NULL, *; /* MAKE NULL PTR */
CPYBWP .ODP, .IFCB-ODP;
ADDSPP .DCB, .ODP, ODP.DCB;
CPYNV GET-ENTRY, DCB-GET;
INITIALIZE-CIPHER-CONTROL:
CPYBLA CTRL-FUNCTION , X'0005'; /* HASH */
CPYBLA CTRL-ALGORITHM, X'01'; /* SHA-1 */
SETSPP .WORK, WORK;
CPYBREP WORK, X'00';
START-HASHING:
CPYBLA CIPHER-SOURCE, " ";
CPYNV CTRL-LENGTH, 1;
CPYBLA CTRL-SEQUENCE, X'01'; /* FIRST */
CIPHER .CIPHER-RESULT, CONTROL, .CIPHER-SOURCE;
GET-NEXT-RECORD:
CALLX .SEPT(GET-ENTRY), GET-OPERATION, *;
CPYBLAP CIPHER-SOURCE, INBUF(13:TEXT-LENGTH), " ";
TRIM-AWAY-EXTRA-TRAILING-BLANKS:
TRIML CTRL-LENGTH, CIPHER-SOURCE, " ";
ADDN(S) CTRL-LENGTH, 1; /* LEAVE EXACTLY ONE BLANK */
CPYBLA CTRL-SEQUENCE, X'02'; /* MIDDLE */
CIPHER .CIPHER-RESULT, CONTROL, .CIPHER-SOURCE;
B GET-NEXT-RECORD;
EOF-DETECTED:
CALLX .SEPT(CLOSE-ENTRY), CLOSE-I, *;
CPYBLA CIPHER-SOURCE, " ";
CPYNV CTRL-LENGTH, 1;
CPYBLA CTRL-SEQUENCE, X'03'; /* FINAL */
CIPHER .CIPHER-RESULT, CONTROL, .CIPHER-SOURCE;
CVTHC PARM-HASH, CIPHER-RESULT;
RTX *;
PEND;
The CIPHER instruction operates with a FIRST record, some MIDDLE
records, and a LAST record. This makes it tricky to deal with members
with less than 3 records (plus requires one to be clairvoyant as the
last record or to buffer things up). I bypass all of these details by always
working with a dummy record containing all blanks before the first real
record and after the last real record. To cater for your wish of being
able to deal with different record lengths, I trim each record to the
length of the last non-blank character + 1 (plus one, because CIPHER
doesn't like a length of zero). As you can see, the first 12 bytes of each
record are ignored.
HTH
Leif
This mailing list archive is Copyright 1997-2026 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.