You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Verwendung des <strong>MD5</strong> <strong>Hash</strong> für die Erzeugung des ZIV Datensatzes<br />
Im Beispiel 1 wird der <strong>MD5</strong> <strong>Hash</strong> jeweils für die Datensätze 1 und 2 gebildet. Parallel<br />
wird der Gesamthash über alle Sätze 1 und 2 für die Speicherung in der Satzart 3<br />
ohne Zwischenspeicherung in einem File gebildet.<br />
Im Beispiel 2 wird eine alternative Form der <strong>Hash</strong>bildung über die Satzart 0 mit<br />
angehängtem Datums- und Zeitstempel aufgezeigt. Diese Form kann z.B. auf<br />
Hostsystemen unter Verwendung des <strong>MD5</strong> REXX Moduls eingesetzt werden.<br />
Beide Varianten werden als gleichwertig für die Ermittlung des <strong>Hash</strong>wertes im<br />
Datensatz 3 akzeptiert.<br />
Beispiel 1:<br />
<strong>MD5</strong>_CTX context_satz12;<br />
unsigned char hash_satz12[16];<br />
<strong>MD5</strong>_CTX context_summe12;<br />
unsigned char hash_summe12[16];<br />
char Satzart_0[800+1];<br />
char Satzart_1[800+1];<br />
char Satzart_2[800+1];<br />
char Satzart_3[800+1];<br />
<strong>MD5</strong>Init(&context_summe12);<br />
Satzart_0 erzeugen und in File speichern<br />
while(Satzart_1 || Satzart_2) // erzeugen<br />
{<br />
if(Satzart_1)<br />
{<br />
<strong>MD5</strong>Init(&context_satz12);<br />
<strong>MD5</strong>Update(&context_satz12, Satzart_1, 608);<br />
<strong>MD5</strong>Final(hash_satz12, &context_satz12);<br />
hash_satz12 in Satzart_1 Feld 27 speichern<br />
50 Byte im Filler für eigene Nutzung ergänzen<br />
<strong>MD5</strong>Update(&context_summe12, Satzart_1, 800);<br />
Satzart_1 in File speichern<br />
}<br />
if(Satzart_2)<br />
{<br />
<strong>MD5</strong>Init(&context_satz12);<br />
<strong>MD5</strong>Update(&context_satz12, Satzart_2, 474);<br />
<strong>MD5</strong>Final(hash_satz12, &context_satz12);<br />
hash_satz12 in Satzart_2 Feld 20 speichern<br />
50 Byte im Filler für eigene Nutzung ergänzen<br />
<strong>MD5</strong>Update(&context_summe12, Satzart_2, 800);<br />
Satzart_2 in File speichern<br />
}<br />
};<br />
Satzart_3 erzeugen<br />
<strong>MD5</strong>Final(hash_summe12, &context_summe12);<br />
hash_summe12 in Satzart_3 Feld 7 speichern<br />
Satzart_3 in File speichern
Beispiel 2:<br />
<strong>MD5</strong>_CTX context_satz12;<br />
unsigned char hash_satz12[16];<br />
<strong>MD5</strong>_CTX context_summe12;<br />
unsigned char hash_summe12[16];<br />
char Satzart_0[800+14+1];<br />
char Satzart_1[800+1];<br />
char Satzart_2[800+1];<br />
char Satzart_3[800+1];<br />
Satzart_0 erzeugen und mit Länge 800 Byte in File speichern<br />
Aktuelles Datum + Uhrzeit + Sekunden JJJJMMTTHHMMSS an Satzart_0 anhängen<br />
z.B. 20060303141516<br />
<strong>MD5</strong>Init(&context_summe12);<br />
<strong>MD5</strong>Update(&context_summe12, Satzart_0, 814);<br />
<strong>MD5</strong>Final(hash_summe12, &context_summe12);<br />
while(Satzart_1 || Satzart_2) // erzeugen<br />
{<br />
if(Satzart_1)<br />
{<br />
<strong>MD5</strong>Init(&context_satz12);<br />
<strong>MD5</strong>Update(&context_satz12, Satzart_1, 608);<br />
<strong>MD5</strong>Final(hash_satz12, &context_satz12);<br />
hash_satz12 in Satzart_1 Feld 27 speichern<br />
50 Byte im Filler für eigene Nutzung ergänzen<br />
Satzart_1 in File speichern<br />
}<br />
if(Satzart_2)<br />
{<br />
<strong>MD5</strong>Init(&context_satz12);<br />
<strong>MD5</strong>Update(&context_satz12, Satzart_2, 474);<br />
<strong>MD5</strong>Final(hash_satz12, &context_satz12);<br />
hash_satz12 in Satzart_2 Feld 20 speichern<br />
50 Byte im Filler für eigene Nutzung ergänzen<br />
Satzart_2 in File speichern<br />
}<br />
};<br />
Satzart_3 erzeugen<br />
hash_summe12 in Satzart_3 Feld 7 speichern<br />
Satzart_3 in File speichern
fc1321.c<br />
#include <br />
#include <br />
#include <br />
typedef unsigned char *POINTER;<br />
typedef unsigned short int UINT2;<br />
typedef unsigned long int UINT4;<br />
/* <strong>MD5</strong> context. */<br />
typedef struct<br />
{<br />
UINT4 state[4];<br />
UINT4 count[2];<br />
unsigned char buffer[64];<br />
} <strong>MD5</strong>_CTX;<br />
#define S11 7<br />
#define S12 12<br />
#define S13 17<br />
#define S14 22<br />
#define S21 5<br />
#define S22 9<br />
#define S23 14<br />
#define S24 20<br />
#define S31 4<br />
#define S32 11<br />
#define S33 16<br />
#define S34 23<br />
#define S41 6<br />
#define S42 10<br />
#define S43 15<br />
#define S44 21<br />
void <strong>MD5</strong>Init(<strong>MD5</strong>_CTX *);<br />
void <strong>MD5</strong>Update(<strong>MD5</strong>_CTX *, unsigned char *, unsigned int);<br />
void <strong>MD5</strong>Final(unsigned char [16], <strong>MD5</strong>_CTX *);<br />
static void <strong>MD5</strong>Transform(UINT4 [4], unsigned char [64]);<br />
static void Encode(unsigned char *, UINT4 *, unsigned int);<br />
static void Decode(UINT4 *, unsigned char *, unsigned int);<br />
static unsigned char PADDING[64] = {<br />
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,<br />
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0<br />
};<br />
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))<br />
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))<br />
#define H(x, y, z) ((x) ^ (y) ^ (z))<br />
#define I(x, y, z) ((y) ^ ((x) | (~z)))<br />
#define ROTATE_LEFT(x, n) (((x) > (32-(n))))<br />
#define FF(a, b, c, d, x, s, ac) { \<br />
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \<br />
(a) = ROTATE_LEFT ((a), (s)); \<br />
(a) += (b); \<br />
}<br />
#define GG(a, b, c, d, x, s, ac) { \<br />
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \<br />
(a) = ROTATE_LEFT ((a), (s)); \<br />
(a) += (b); \<br />
}<br />
#define HH(a, b, c, d, x, s, ac) { \<br />
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \<br />
(a) = ROTATE_LEFT ((a), (s)); \<br />
(a) += (b); \<br />
}<br />
#define II(a, b, c, d, x, s, ac) { \<br />
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \<br />
(a) = ROTATE_LEFT ((a), (s)); \<br />
(a) += (b); \<br />
}<br />
void <strong>MD5</strong>Init(<strong>MD5</strong>_CTX *context)
{<br />
context->count[0] = context->count[1] = 0;<br />
context->state[0] = 0x67452301;<br />
context->state[1] = 0xefcdab89;<br />
context->state[2] = 0x98badcfe;<br />
context->state[3] = 0x10325476;<br />
}<br />
void <strong>MD5</strong>Update(<strong>MD5</strong>_CTX *context, unsigned char *input, unsigned int inputLen)<br />
{<br />
unsigned int i, index, partLen;<br />
}<br />
index = (unsigned int)((context->count[0] >> 3) & 0x3F);<br />
if((context->count[0] += ((UINT4)inputLen count[1] += ((UINT4)inputLen >> 29);<br />
partLen = 64 - index;<br />
if(inputLen >= partLen)<br />
{<br />
memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);<br />
<strong>MD5</strong>Transform(context->state, context->buffer);<br />
for(i = partLen; i + 63 < inputLen; i += 64)<br />
<strong>MD5</strong>Transform(context->state, &input[i]);<br />
index = 0;<br />
}<br />
else<br />
i = 0;<br />
memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],<br />
inputLen-i);<br />
void <strong>MD5</strong>Final(unsigned char digest[16], <strong>MD5</strong>_CTX *context)<br />
{<br />
unsigned char bits[8];<br />
unsigned int index, padLen;<br />
Encode (bits, context->count, 8);<br />
index = (unsigned int)((context->count[0] >> 3) & 0x3f);<br />
padLen = (index < 56) ? (56 - index) : (120 - index);<br />
<strong>MD5</strong>Update(context, PADDING, padLen);<br />
<strong>MD5</strong>Update(context, bits, 8);<br />
Encode(digest, context->state, 16);<br />
memset((POINTER)context, 0, sizeof (*context));<br />
}<br />
static void <strong>MD5</strong>Transform(UINT4 state[4], unsigned char block[64])<br />
{<br />
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];<br />
Decode(x, block, 64);<br />
/* Round 1 */<br />
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */<br />
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */<br />
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */<br />
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */<br />
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */<br />
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */<br />
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */<br />
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */<br />
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */<br />
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */<br />
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */<br />
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */<br />
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */<br />
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */<br />
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */<br />
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */<br />
/* Round 2 */<br />
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */<br />
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */<br />
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
}<br />
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */<br />
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */<br />
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */<br />
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */<br />
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */<br />
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */<br />
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */<br />
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */<br />
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */<br />
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */<br />
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */<br />
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */<br />
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */<br />
/* Round 3 */<br />
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */<br />
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */<br />
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */<br />
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */<br />
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */<br />
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */<br />
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */<br />
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */<br />
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */<br />
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */<br />
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */<br />
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */<br />
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */<br />
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */<br />
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */<br />
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */<br />
/* Round 4 */<br />
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */<br />
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */<br />
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */<br />
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */<br />
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */<br />
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */<br />
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */<br />
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */<br />
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */<br />
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */<br />
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */<br />
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */<br />
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */<br />
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */<br />
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */<br />
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */<br />
state[0] += a;<br />
state[1] += b;<br />
state[2] += c;<br />
state[3] += d;<br />
memset((POINTER)x, 0, sizeof(x));<br />
static void Encode(unsigned char *output, UINT4 *input, unsigned int len)<br />
{<br />
unsigned int i, j;<br />
for(i = 0, j = 0; j < len; i++, j += 4)<br />
{<br />
output[j] = (unsigned char)(input[i] & 0xff);<br />
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);<br />
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);<br />
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);<br />
}<br />
}<br />
static void Decode(UINT4 *output, unsigned char *input, unsigned int len)<br />
{<br />
unsigned int i, j;<br />
for(i = 0, j = 0; j < len; i++, j += 4)<br />
{
}<br />
}<br />
output[i] = ((UINT4)input[j]) |<br />
(((UINT4)input[j+1])
* Prints a message digest in hexadecimal.<br />
*/<br />
static void MDPrint(unsigned char digest[16])<br />
{<br />
unsigned int i;<br />
}<br />
for (i = 0; i < 16; i++)<br />
printf ("%02x", digest[i]);
Calling REXX from COBOL on OS/390 and z/OS<br />
Beispiele des Upros für COBOL unter:<br />
http://www-1.ibm.com/support/docview.wss?uid=swg24003837<br />
und zwar dort das Member SIEXCOB.JCLSAMPL (muss modifiziert werden).<br />
Aufruf aus COBOL:<br />
*---------------------------------------------------------------<br />
* 2170-PRUEFEN-SATZ-HASH<br />
* - SATZ HASH ERMITTELN UEBER UPRO REXX<strong>MD5</strong><br />
*---------------------------------------------------------------<br />
2170-PRUEFEN-SATZ-HASH SECTION.<br />
*<br />
CALL 'REXX<strong>MD5</strong>' USING <strong>MD5</strong>-STRING-VORHER<br />
<strong>MD5</strong>-STRING-LAENGE<br />
<strong>MD5</strong>-HASH-NACHHER<br />
<strong>MD5</strong>-RETURN-CODE<br />
IF <strong>MD5</strong>-RETURN-CODE = ZERO<br />
CONTINUE<br />
ELSE<br />
MOVE <strong>MD5</strong>-RETURN-CODE TO DISP-<strong>MD5</strong>-RETURN-CODE<br />
STRING 'FEHLER IN MODUL ERMITTELN HASHWERT'<br />
' MODUL NAME: ' PGM-REXX<strong>MD5</strong><br />
DELIMITED BY SIZE<br />
INTO F-KOMMENTAR1<br />
STRING 'RETURNCODE: '<br />
DISP-<strong>MD5</strong>-RETURN-CODE<br />
DELIMITED BY SIZE<br />
INTO F-KOMMENTAR2<br />
END-IF<br />
CONTINUE.<br />
*<br />
2170-EXIT.<br />
EXIT.<br />
*<br />
REXX-Proc Library einbauen im Run-JCL:<br />
//SYSEXEC DD DISP=SHR,DSN=UserId.TSO.CLIST<br />
*<br />
* Sample JCL for calling IRXEXEC from COBOL program<br />
* You may modify this sample for your needs by including<br />
* a REXX of your own. The argument for the REXX procedure<br />
* may be taylored for your needs.<br />
*<br />
Identification Division.<br />
PROGRAM-ID. REXX<strong>MD5</strong>.<br />
Environment division.<br />
Configuration section.<br />
Special-names.<br />
Input-output section.<br />
File-control.<br />
Data division.<br />
File section.<br />
*<br />
Working-storage section.<br />
01 Working-storage-for-rexxmd5 pic x.<br />
77 PGM-NAME pic X(8).
* Define the IRXEXEC argument blocks<br />
*<br />
01 EXECBLK.<br />
03 EXECBLK-ACRYN pic X(8).<br />
03 EXECBLK-LENGTH pic S9(8) binary.<br />
03 EXECBLK-reserved pic S9(8) binary.<br />
03 EXECBLK-MEMBER pic X(8).<br />
03 EXECBLK-DDNAME pic X(8).<br />
03 EXECBLK-SUBCOM pic X(8).<br />
03 EXECBLK-DSNPTR POINTER.<br />
03 EXECBLK-DSNLEN pic 9(4) comp.<br />
01 EVALBLK.<br />
03 EVALBLK-EVPAD1 pic S9(8) binary.<br />
03 EVALBLK-EVSIZE pic S9(8) binary.<br />
03 EVALBLK-EVLEN pic S9(8) binary.<br />
03 EVALBLK-EVPAD2 pic S9(8) binary.<br />
03 EVALBLK-EVDATA pic x(256).<br />
77 flags pic S9(8) binary.<br />
77 REXX-return-code pic S9(8) binary.<br />
77 dummy-zero pic S9(8) binary.<br />
01 ARGUMENT.<br />
02 ARGUMENT-1 OCCURS 1 TIMES.<br />
05 ARGSTRING-PTR POINTER.<br />
05 ARGSTRING-LENGTH pic S9(8) binary.<br />
02 ARGSTRING-LAST1 pic S9(8) binary.<br />
02 ARGSTRING-LAST2 pic S9(8) binary.<br />
77 arg1 pic x(800).<br />
77 execblk-ptr POINTER.<br />
77 argtable-ptr POINTER.<br />
77 evalblk-ptr POINTER.<br />
linkage section.<br />
copy rexxmd5c.<br />
*****************************************************************<br />
*** D O M A I N L O G I C **<br />
*****************************************************************<br />
procedure division using md5-string-vorher<br />
md5-string-laenge<br />
md5-hash-nachher<br />
md5-return-code.<br />
000-do-main-logic.<br />
display "PROGRAM rexxmd5 - Beginning"<br />
*--- Pass md5-string-vor as argument to the REXX procedure '<strong>MD5</strong>'<br />
move md5-string-vorher to arg1<br />
call "GET-ARG1-PTR" using arg1 ARGSTRING-PTR(1)<br />
move md5-string-laenge to ARGSTRING-LENGTH(1)<br />
move -1 to ARGSTRING-LAST1<br />
move -1 to ARGSTRING-LAST2<br />
call 'GET-ARGUMENT-PTR' using argument argtable-ptr<br />
move 'IRXEXECB' to EXECBLK-ACRYN<br />
move 48 to EXECBLK-LENGTH<br />
move 0 to EXECBLK-reserved<br />
*--- Pass the procedure name <strong>MD5</strong> to IRXEXEC.<br />
move "<strong>MD5</strong>" to EXECBLK-MEMBER<br />
move space to EXECBLK-SUBCOM<br />
move space to EXECBLK-DDNAME<br />
set EXECBLK-DSNPTR to NULL<br />
move 0 to EXECBLK-DSNLEN<br />
call "GET-EXECBLK-PTR" using EXECBLK execblk-ptr<br />
move zero to EVALBLK-EVPAD1<br />
move 34 to EVALBLK-EVSIZE<br />
move zero to EVALBLK-EVLEN<br />
move zero to EVALBLK-EVPAD2<br />
call "GET-EVALBLK-PTR" using EVALBLK evalblk-ptr<br />
move zero to dummy-zero<br />
*--- Set flags to HEX 20000000<br />
* i.e. exec invoked as subroutine<br />
move 536870912 to flags<br />
move zero to REXX-return-code
*--- Call the REXX exec --move<br />
'IRXEXEC ' to PGM-NAME<br />
CALL PGM-NAME USING execblk-ptr<br />
argtable-ptr<br />
flags<br />
dummy-zero<br />
dummy-zero<br />
evalblk-ptr<br />
dummy-zero<br />
dummy-zero<br />
dummy-zero<br />
REXX-return-code<br />
CANCEL PGM-NAME<br />
*--- Display the return code<br />
move evalblk-evdata to md5-hash-nachher<br />
move rexx-return-code to md5-return-code<br />
display "REXX return code is: " REXX-return-code<br />
display "REXX result is: " EVALBLK-EVDATA<br />
display "PROGRAM rexxmd5 - Normal end"<br />
goback.<br />
*--- Addressing helper<br />
Identification Division.<br />
Program-id. GET-ARG1-PTR.<br />
Environment division.<br />
Data division.<br />
Working-storage section.<br />
Linkage section.<br />
77 arg1 pic x(800).<br />
77 arg-ptr POINTER.<br />
procedure division using arg1 arg-ptr.<br />
set arg-ptr to address of arg1<br />
goback.<br />
end program GET-ARG1-PTR.<br />
*--- Addressing helper<br />
Identification Division.<br />
Program-id. GET-ARGUMENT-PTR.<br />
Environment division.<br />
Data division.<br />
Working-storage section.<br />
Linkage section.<br />
01 ARGUMENT.<br />
02 ARGUMENT-1 OCCURS 1 TIMES.<br />
05 ARGSTRING-PTR POINTER.<br />
05 ARGSTRING-LENGTH pic S9(8) binary.<br />
02 ARGSTRING-LAST1 pic S9(8) binary.<br />
02 ARGSTRING-LAST2 pic S9(8) binary.<br />
77 argtable-ptr POINTER.<br />
procedure division using ARGUMENT argtable-ptr.<br />
set argtable-ptr to address of ARGUMENT<br />
goback.<br />
end program GET-ARGUMENT-PTR.<br />
*--- Addressing helper<br />
Identification Division.<br />
Program-id. GET-EXECBLK-PTR.<br />
Environment division.<br />
Data division.<br />
Working-storage section.<br />
Linkage section.<br />
01 EXECBLK.<br />
03 EXECBLK-ACRYN pic X(8).<br />
03 EXECBLK-LENGTH pic 9(4) comp.<br />
03 EXECBLK-reserved pic 9(4) comp.<br />
03 EXECBLK-MEMBER pic X(8).<br />
03 EXECBLK-DDNAME pic X(8).<br />
03 EXECBLK-SUBCOM pic X(8).<br />
03 EXECBLK-DSNPTR POINTER.<br />
03 EXECBLK-DSNLEN pic 9(4) comp.
77 execblk-ptr POINTER.<br />
procedure division using EXECBLK execblk-ptr.<br />
set execblk-ptr to address of EXECBLK<br />
goback.<br />
end program GET-EXECBLK-PTR.<br />
*--- Addressing helper<br />
Identification Division.<br />
Program-id. GET-EVALBLK-PTR.<br />
Environment division.<br />
Data division.<br />
Working-storage section.<br />
Linkage section.<br />
01 EVALBLK.<br />
03 EVALBLK-EVPAD1 pic 9(4) binary.<br />
03 EVALBLK-EVSIZE pic 9(4) binary.<br />
03 EVALBLK-EVLEN pic 9(4) binary.<br />
03 EVALBLK-EVPAD2 pic 9(4) binary.<br />
03 EVALBLK-EVDATA pic x(256).<br />
77 evalblk-ptr POINTER.<br />
procedure division using EVALBLK evalblk-ptr.<br />
set evalblk-ptr to address of EVALBLK<br />
goback.<br />
end program GET-EVALBLK-PTR.<br />
IA9990 END PROGRAM REXX<strong>MD5</strong>.<br />
REXX<strong>MD5</strong>C1<br />
***************************************************************<br />
* Europaeische Zinsverordnung (EUZI)<br />
*<br />
* Eingabeschnittstelle zum ermitteln der <strong>MD5</strong> hash Werte<br />
* Es werden die folgenden Felder an das Upro "REXX<strong>MD5</strong>"<br />
* uebergeben<br />
*****************************************************************<br />
*<br />
*<br />
01 <strong>MD5</strong>-STRING-VORHER PIC X(800).<br />
* Eingabe String fuer <strong>MD5</strong><br />
*<br />
01 <strong>MD5</strong>-STRING-LAENGE PIC S9(08) BINARY.<br />
* Eingabe String laenge<br />
* muss - da sonst Ergebnis<br />
* nicht korrekt (<strong>MD5</strong>-HASH-NACHHER)<br />
*<br />
01 <strong>MD5</strong>-HASH-NACHHER PIC X(32).<br />
* Rueckgabe <strong>Hash</strong>wert<br />
*<br />
01 <strong>MD5</strong>-RETURN-CODE PIC S9(08) BINARY.<br />
* Rueckgabe return Code<br />
*
REXX- <strong>MD5</strong>-Procedure<br />
/* REXX */<br />
RETURN <strong>MD5</strong>(ARG(1))<br />
/* --- */<br />
<strong>MD5</strong> : procedure /* for <strong>MD5</strong> details see RfC 1321 */<br />
numeric digits 11 /* 32 bit addition + carry digit */<br />
parse arg MSG /* if MSG < 12,500,000,000 bytes */<br />
LEN = 8 * length( MSG ) /* <strong>MD5</strong> operates on bit messages: */<br />
PAD = LEN // 512 /* pad to length 448 modulo 512 */<br />
if PAD < 448 then PAD = 448 - PAD<br />
else PAD = 960 - PAD<br />
PAD = left( '80'x, PAD / 8, '00'x )<br />
MSG = MSG !! PAD !! reverse( x2c( d2x( LEN, 16 )))<br />
A = '67452301'x ;<br />
C = '98BADCFE'x ;<br />
S11 = 7 ; S12 = 12 ;<br />
S21 = 5 ; S22 = 9 ;<br />
S31 = 4 ; S32 = 11 ;<br />
S41 = 6 ; S42 = 10 ;<br />
B = 'EFCDAB89'x<br />
D = '10325476'x<br />
S13 = 17 ; S14 = 22<br />
S23 = 14 ; S24 = 20<br />
S33 = 16 ; S34 = 23<br />
S43 = 15 ; S44 = 21<br />
do N = 1 to ( length( MSG ) / 4 ) / 16<br />
K = N * 64 - 63<br />
do J = 0 to 15<br />
M.J = c2d( reverse( substr( MSG, K + J * 4, 4 )))<br />
end J<br />
AA = A ; BB = B ; CC = C ; DD = D<br />
A = <strong>MD5</strong>.1( A, B, C, D, S11, M.0 + 3614090360 ) /* 1 */<br />
D = <strong>MD5</strong>.1( D, A, B, C, S12, M.1 + 3905402710 ) /* 2 */<br />
C = <strong>MD5</strong>.1( C, D, A, B, S13, M.2 + 606105819 ) /* 3 */<br />
B = <strong>MD5</strong>.1( B, C, D, A, S14, M.3 + 3250441966 ) /* 4 */<br />
A = <strong>MD5</strong>.1( A, B, C, D, S11, M.4 + 4118548399 ) /* 5 */<br />
D = <strong>MD5</strong>.1( D, A, B, C, S12, M.5 + 1200080426 ) /* 6 */<br />
C = <strong>MD5</strong>.1( C, D, A, B, S13, M.6 + 2821735955 ) /* 7 */<br />
B = <strong>MD5</strong>.1( B, C, D, A, S14, M.7 + 4249261313 ) /* 8 */<br />
A = <strong>MD5</strong>.1( A, B, C, D, S11, M.8 + 1770035416 ) /* 9 */<br />
D = <strong>MD5</strong>.1( D, A, B, C, S12, M.9 + 2336552879 ) /* 10 */<br />
C = <strong>MD5</strong>.1( C, D, A, B, S13, M.10+ 4294925233 ) /* 11 */<br />
B = <strong>MD5</strong>.1( B, C, D, A, S14, M.11+ 2304563134 ) /* 12 */<br />
A = <strong>MD5</strong>.1( A, B, C, D, S11, M.12+ 1804603682 ) /* 13 */<br />
D = <strong>MD5</strong>.1( D, A, B, C, S12, M.13+ 4254626195 ) /* 14 */<br />
C = <strong>MD5</strong>.1( C, D, A, B, S13, M.14+ 2792965006 ) /* 15 */<br />
B = <strong>MD5</strong>.1( B, C, D, A, S14, M.15+ 1236535329 ) /* 16 */<br />
A = <strong>MD5</strong>.2( A, B, C, D, S21, M.1 + 4129170786 ) /* 17 */<br />
D = <strong>MD5</strong>.2( D, A, B, C, S22, M.6 + 3225465664 ) /* 18 */<br />
C = <strong>MD5</strong>.2( C, D, A, B, S23, M.11+ 643717713 ) /* 19 */<br />
B = <strong>MD5</strong>.2( B, C, D, A, S24, M.0 + 3921069994 ) /* 20 */<br />
A = <strong>MD5</strong>.2( A, B, C, D, S21, M.5 + 3593408605 ) /* 21 */<br />
D = <strong>MD5</strong>.2( D, A, B, C, S22, M.10+ 38016083 ) /* 22 */<br />
C = <strong>MD5</strong>.2( C, D, A, B, S23, M.15+ 3634488961 ) /* 23 */<br />
B = <strong>MD5</strong>.2( B, C, D, A, S24, M.4 + 3889429448 ) /* 24 */<br />
A = <strong>MD5</strong>.2( A, B, C, D, S21, M.9 + 568446438 ) /* 25 */<br />
D = <strong>MD5</strong>.2( D, A, B, C, S22, M.14+ 3275163606 ) /* 26 */<br />
C = <strong>MD5</strong>.2( C, D, A, B, S23, M.3 + 4107603335 ) /* 27 */<br />
B = <strong>MD5</strong>.2( B, C, D, A, S24, M.8 + 1163531501 ) /* 28 */<br />
A = <strong>MD5</strong>.2( A, B, C, D, S21, M.13+ 2850285829 ) /* 29 */<br />
D = <strong>MD5</strong>.2( D, A, B, C, S22, M.2 + 4243563512 ) /* 30 */<br />
C = <strong>MD5</strong>.2( C, D, A, B, S23, M.7 + 1735328473 ) /* 31 */<br />
B = <strong>MD5</strong>.2( B, C, D, A, S24, M.12+ 2368359562 ) /* 32 */<br />
A = <strong>MD5</strong>.3( A, B, C, D, S31, M.5 + 4294588738 ) /* 33 */<br />
D = <strong>MD5</strong>.3( D, A, B, C, S32, M.8 + 2272392833 ) /* 34 */<br />
C = <strong>MD5</strong>.3( C, D, A, B, S33, M.11+ 1839030562 ) /* 35 */<br />
B = <strong>MD5</strong>.3( B, C, D, A, S34, M.14+ 4259657740 ) /* 36 */<br />
A = <strong>MD5</strong>.3( A, B, C, D, S31, M.1 + 2763975236 ) /* 37 */<br />
D = <strong>MD5</strong>.3( D, A, B, C, S32, M.4 + 1272893353 ) /* 38 */<br />
C = <strong>MD5</strong>.3( C, D, A, B, S33, M.7 + 4139469664 ) /* 39 */<br />
B = <strong>MD5</strong>.3( B, C, D, A, S34, M.10+ 3200236656 ) /* 40 */<br />
A = <strong>MD5</strong>.3( A, B, C, D, S31, M.13+ 681279174 ) /* 41 */
D = <strong>MD5</strong>.3( D, A, B, C, S32, M.0 + 3936430074 ) /* 42 */<br />
C = <strong>MD5</strong>.3( C, D, A, B, S33, M.3 + 3572445317 ) /* 43 */<br />
B = <strong>MD5</strong>.3( B, C, D, A, S34, M.6 + 76029189 ) /* 44 */<br />
A = <strong>MD5</strong>.3( A, B, C, D, S31, M.9 + 3654602809 ) /* 45 */<br />
D = <strong>MD5</strong>.3( D, A, B, C, S32, M.12+ 3873151461 ) /* 46 */<br />
C = <strong>MD5</strong>.3( C, D, A, B, S33, M.15+ 530742520 ) /* 47 */<br />
B = <strong>MD5</strong>.3( B, C, D, A, S34, M.2 + 3299628645 ) /* 48 */<br />
A = <strong>MD5</strong>.4( A, B, C, D, S41, M.0 + 4096336452 ) /* 49 */<br />
D = <strong>MD5</strong>.4( D, A, B, C, S42, M.7 + 1126891415 ) /* 50 */<br />
C = <strong>MD5</strong>.4( C, D, A, B, S43, M.14+ 2878612391 ) /* 51 */<br />
B = <strong>MD5</strong>.4( B, C, D, A, S44, M.5 + 4237533241 ) /* 52 */<br />
A = <strong>MD5</strong>.4( A, B, C, D, S41, M.12+ 1700485571 ) /* 53 */<br />
D = <strong>MD5</strong>.4( D, A, B, C, S42, M.3 + 2399980690 ) /* 54 */<br />
C = <strong>MD5</strong>.4( C, D, A, B, S43, M.10+ 4293915773 ) /* 55 */<br />
B = <strong>MD5</strong>.4( B, C, D, A, S44, M.1 + 2240044497 ) /* 56 */<br />
A = <strong>MD5</strong>.4( A, B, C, D, S41, M.8 + 1873313359 ) /* 57 */<br />
D = <strong>MD5</strong>.4( D, A, B, C, S42, M.15+ 4264355552 ) /* 58 */<br />
C = <strong>MD5</strong>.4( C, D, A, B, S43, M.6 + 2734768916 ) /* 59 */<br />
B = <strong>MD5</strong>.4( B, C, D, A, S44, M.13+ 1309151649 ) /* 60 */<br />
A = <strong>MD5</strong>.4( A, B, C, D, S41, M.4 + 4149444226 ) /* 61 */<br />
D = <strong>MD5</strong>.4( D, A, B, C, S42, M.11+ 3174756917 ) /* 62 */<br />
C = <strong>MD5</strong>.4( C, D, A, B, S43, M.2 + 718787259 ) /* 63 */<br />
B = <strong>MD5</strong>.4( B, C, D, A, S44, M.9 + 3951481745 ) /* 64 */<br />
A = x2c( d2x( c2d( AA ) + c2d( A ), 8 ))<br />
B = x2c( d2x( c2d( BB ) + c2d( B ), 8 ))<br />
C = x2c( d2x( c2d( CC ) + c2d( C ), 8 ))<br />
D = x2c( d2x( c2d( DD ) + c2d( D ), 8 ))<br />
end N<br />
A = reverse( A ) ; B = reverse( B )<br />
C = reverse( C ) ; D = reverse( D )<br />
return translate( c2x( A !! B !! C !! D ), 'abcdef', 'ABCDEF' )<br />
<strong>MD5</strong>.1 : procedure /* function used in <strong>MD5</strong> round 1: */<br />
parse arg A, B, C, D, S, M<br />
C = bitor( bitand( B, C ), bitand( D, bitxor( B,, 'FF'x )))<br />
signal <strong>MD5</strong>..<br />
<strong>MD5</strong>.2 : procedure /* function used in <strong>MD5</strong> round 2: */<br />
parse arg A, B, C, D, S, M<br />
C = bitor( bitand( B, D ), bitand( C, bitxor( D,, 'FF'x )))<br />
signal <strong>MD5</strong>..<br />
<strong>MD5</strong>.3 : procedure /* function used in <strong>MD5</strong> round 3: */<br />
parse arg A, B, C, D, S, M<br />
C = bitxor( B, bitxor( C, D ))<br />
signal <strong>MD5</strong>..<br />
<strong>MD5</strong>.4 : procedure /* function used in <strong>MD5</strong> round 4: */<br />
parse arg A, B, C, D, S, M<br />
C = bitxor( C, bitor( B, bitxor( D,, 'FF'x )))<br />
<strong>MD5</strong>.. :<br />
C = x2b( d2x( c2d( A ) + c2d( C ) + M, 8 ))<br />
C = x2d( b2x( right( C !! left( C, S ), 32 )))<br />
return x2c( d2x( C + c2d( B ), 8 ))