× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@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





As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

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.