|
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
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 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.