logical XOR operator in Progress

雨燕双飞 提交于 2019-12-11 12:03:06

问题


Is there XOR operator in Progress?
There is AND, OR and NOT, so, i can code "XOR" like this:

(a OR b) AND NOT (a AND b)

I just want to know if the operator exists (with another name).

Thanks.


回答1:


Unfortunately, there is no such inbuilt operator in Progress. You can implement it in the way you said.




回答2:


There is no built-in XOR. But you might find this helpful:

   /*  _md5.i
       RSA Data Security, Inc. MD5 Message-Digest Algorithm
       Progress implementation courtesy Ultramain Systems, Inc.
       12/20/00 Andrew Brooman
    */
    &IF DEFINED ( BROOMAN_MD5_IMPLEMENTATION ) EQ 0 &THEN
    &GLOBAL-DEFINE BROOMAN_MD5_IMPLEMENTATION
    /* 12/20/00 Andrew Brooman


   NOTES:
   1) The MD5 algorithm is described at www.landfield.com/rfcs/rfc1321.html.
   2) For ease of debugging, I have used the variable names from the algorithm
      as described (e.g. M, A, B, C, D, X, Y, Z, FF, GG, HH, II) hence the
      inconsistency with Progress naming conventions (e.g. cMessage).
   3) A "word" in this algorithm is a long word (32 bits).
   4) Progress INTEGERs are signed long words.  Despite the signing,
      AND, OR, XOR, NOT, Shift, Add seem to work fine.  You will notice
      use of negative numbers (e.g. initializing MD5 buffers A B C D) when
      the high-order bit needs to be set.

      MAX INT = +2147483647
      MIN INT = -2147483648

      MAX INT + 1 = MIN INT (overflows)

  29 Aug 2006 Greg Higgins
     Removed Functions to _md5.i
     Added Preprocessor BROOMAN_MD5_IMPLEMENTATION
     Added some ASSIGN statements

*/
/* bitwise logical operations on long words */

FUNCTION bitAND RETURNS INTEGER (INPUT X AS INTEGER, INPUT Y AS INTEGER):
   DEFINE VARIABLE b1 AS INTEGER NO-UNDO.
   DEFINE VARIABLE b2 AS INTEGER NO-UNDO.
   DEFINE VARIABLE n  AS INTEGER NO-UNDO.
   DEFINE VARIABLE Z  AS INTEGER NO-UNDO.

   DO n = 1 TO 32:
     ASSIGN
       b1 = GET-BITS(X, n, 1)
       b2 = GET-BITS(Y, n, 1)
       .
       IF b1 = 1 AND b2 = 1 THEN PUT-BITS(Z, n, 1) = 1.
   END.

   RETURN Z.
END FUNCTION.

FUNCTION bitNOT RETURNS INTEGER (INPUT X AS INTEGER):
   DEFINE VARIABLE b AS INTEGER NO-UNDO.
   DEFINE VARIABLE n AS INTEGER NO-UNDO.
   DEFINE VARIABLE Z AS INTEGER NO-UNDO.

   DO n = 1 TO 32:
       b = GET-BITS(X, n, 1).
       IF b = 0 THEN PUT-BITS(Z, n, 1) = 1.
   END.

   RETURN Z.
END FUNCTION.

FUNCTION bitOR RETURNS INTEGER (INPUT X AS INTEGER, INPUT Y AS INTEGER):
   DEFINE VARIABLE b1 AS INTEGER NO-UNDO.
   DEFINE VARIABLE b2 AS INTEGER NO-UNDO.
   DEFINE VARIABLE n  AS INTEGER NO-UNDO.
   DEFINE VARIABLE Z  AS INTEGER NO-UNDO.

   DO n = 1 TO 32:
     ASSIGN
       b1 = GET-BITS(X, n, 1)
       b2 = GET-BITS(Y, n, 1)
       .
       IF b1 = 1 OR b2 = 1 THEN PUT-BITS(Z, n, 1) = 1.
   END.

   RETURN Z.
END FUNCTION.

FUNCTION bitShift RETURNS INTEGER (INPUT X AS INTEGER, INPUT S AS INTEGER):
   DEFINE VARIABLE Z AS INTEGER NO-UNDO.

   ASSIGN
     PUT-BITS(Z, 1, s)          = GET-BITS(X, 33 - s, s)
     PUT-BITS(Z, s + 1, 32 - s) = GET-BITS(X, 1, 32 - s)
     .

   RETURN Z.
END FUNCTION.

FUNCTION bitXOR RETURNS INTEGER (INPUT X AS INTEGER, INPUT Y AS INTEGER):
   DEFINE VARIABLE b1 AS INTEGER NO-UNDO.
   DEFINE VARIABLE b2 AS INTEGER NO-UNDO.
   DEFINE VARIABLE n  AS INTEGER NO-UNDO.
   DEFINE VARIABLE Z  AS INTEGER NO-UNDO.

   DO n = 1 TO 32:
     ASSIGN
       b1 = GET-BITS(X, n, 1)
       b2 = GET-BITS(Y, n, 1)
       .
       IF b1 + b2 = 1 THEN PUT-BITS(Z, n, 1) = 1.
   END.

   RETURN Z.
END FUNCTION.

/* function to convert integer to hex (starting with low order byte first) */

FUNCTION hexGet RETURNS CHARACTER (INPUT X AS INTEGER):
   DEFINE VARIABLE b1 AS INTEGER NO-UNDO.
   DEFINE VARIABLE b2 AS INTEGER NO-UNDO.
   DEFINE VARIABLE n  AS INTEGER NO-UNDO.
   DEFINE VARIABLE h  AS CHARACTER NO-UNDO INITIAL "0123456789abcdef".
   DEFINE VARIABLE Z  AS CHARACTER NO-UNDO.

   DO n = 0 TO 3:
     ASSIGN
       b1 = GET-BITS(X, n * 8 + 5, 4)
       b2 = GET-BITS(X, n * 8 + 1, 4)
       .
       Z = Z + SUBSTRING(h, b1 + 1, 1) + SUBSTRING(h, b2 + 1, 1).
   END.

   RETURN Z.
END FUNCTION.

/* MD5 operations */

FUNCTION F RETURNS INTEGER(INPUT X AS INTEGER, INPUT Y AS INTEGER,
INPUT Z AS INTEGER):
   RETURN bitOR(bitAND(X,Y), bitAND(bitNOT(X),Z)).
END FUNCTION.

FUNCTION G RETURNS INTEGER(INPUT X AS INTEGER, INPUT Y AS INTEGER,
INPUT Z AS INTEGER):
   RETURN bitOR(bitAND(X, Z), bitAND(Y, bitNOT(Z))).
END FUNCTION.

FUNCTION H RETURNS INTEGER(INPUT X AS INTEGER, INPUT Y AS INTEGER,
INPUT Z AS INTEGER):
   RETURN bitXOR(bitXOR(X, Y), Z).
END FUNCTION.

FUNCTION I RETURNS INTEGER(INPUT X AS INTEGER, INPUT Y AS INTEGER,
INPUT Z AS INTEGER):
   RETURN bitXOR(Y, bitOR(X, bitNOT(Z))).
END FUNCTION.

/* in the following operations, notice the values for X[k] and T[i]
  are passed in rather than looked up--slight deviation from standard */

PROCEDURE Round1:
   DEFINE INPUT-OUTPUT PARAMETER a AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER b  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER c  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER d  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Xk AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER s  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Ti AS INTEGER NO-UNDO.

   a = b + bitShift(a + F(b, c, d) + Xk + Ti, s).
END PROCEDURE.

PROCEDURE Round2:
   DEFINE INPUT-OUTPUT PARAMETER a AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER b  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER c  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER d  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Xk AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER s  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Ti AS INTEGER NO-UNDO.

   a = b + bitShift(a + G(b, c, d) + Xk + Ti, s).
END PROCEDURE.

PROCEDURE Round3:
   DEFINE INPUT-OUTPUT PARAMETER a AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER b  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER c  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER d  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Xk AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER s  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Ti AS INTEGER NO-UNDO.

   a = b + bitShift(a + H(b, c, d) + Xk + Ti, s).
END PROCEDURE.

PROCEDURE Round4:
   DEFINE INPUT-OUTPUT PARAMETER a AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER b  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER c  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER d  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Xk AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER s  AS INTEGER NO-UNDO.
   DEFINE INPUT PARAMETER Ti AS INTEGER NO-UNDO.

   a = b + bitShift(a + I(b, c, d) + Xk + Ti, s).
END PROCEDURE.

/* main function to compute an MD5 digest */

FUNCTION MD5 RETURNS CHARACTER (INPUT cMessage AS CHARACTER):
   DEFINE VARIABLE A  AS INTEGER NO-UNDO.
   DEFINE VARIABLE AA AS INTEGER NO-UNDO.
   DEFINE VARIABLE B  AS INTEGER NO-UNDO.
   DEFINE VARIABLE BB AS INTEGER NO-UNDO.
   DEFINE VARIABLE C  AS INTEGER NO-UNDO.
   DEFINE VARIABLE CC AS INTEGER NO-UNDO.
   DEFINE VARIABLE D  AS INTEGER NO-UNDO.
   DEFINE VARIABLE DD AS INTEGER NO-UNDO.
   DEFINE VARIABLE i  AS INTEGER NO-UNDO.
   DEFINE VARIABLE j  AS INTEGER NO-UNDO.
   DEFINE VARIABLE M  AS MEMPTR  NO-UNDO.
   DEFINE VARIABLE N  AS INTEGER NO-UNDO.
   DEFINE VARIABLE X  AS INTEGER NO-UNDO EXTENT 16.

   DEFINE VARIABLE cDigest    AS CHARACTER NO-UNDO.
   DEFINE VARIABLE iLenOrig   AS INTEGER   NO-UNDO.
   DEFINE VARIABLE iLenPadded AS INTEGER   NO-UNDO.
   DEFINE VARIABLE iPadding   AS INTEGER   NO-UNDO.

   /* compute original message length */

   iLenOrig = LENGTH(cMessage).

   /* compute padded message length:
      a) must be a multiple of 64 bytes
      b) must have at least 9 bytes of padding
   */

   iPadding = 64 - iLenOrig MOD 64.
   IF iPadding < 9 THEN iPadding = iPadding + 64.
   iLenPadded = iLenOrig + iPadding.

   /* create MEMPTR to hold message since we need to manipulate bits,
bytes, and long words */

   ASSIGN
     SET-SIZE(M)       = iLenPadded
     SET-BYTE-ORDER(M) = 3   /* little-endian */
     .
   /* add padding */

   ASSIGN
     PUT-STRING(M, 1, iLenOrig)  = cMessage
     PUT-BYTE(M, iLenOrig + 1)   = 128
     PUT-LONG(M, iLenPadded - 7) = iLenOrig * 8
     .

   /* initialize MD registers */

   ASSIGN
     A =  1732584193
     B =  -271733879
     C = -1732584194
     D =   271733878
     .

   /* process message in N blocks of 16 words (64 bytes) */

   N = iLenPadded / 64 - 1.

   DO i = 0 TO N:

       /* copy 16 words into working buffer X */

       DO j = 0 TO 15:
           X[j + 1] = GET-LONG(M, i * 64 + j * 4 + 1).
       END.

       /* store current MD5 registers */
       ASSIGN
         AA = A
         BB = B
         CC = C
         DD = D
         .

       /* note: in the following rounds, minor changes were made:
          a) X[k] is passed rather than k
          b) T[i] is passed rather that i
          c) because Progress has one based arrays, the subscript
             for X[k] is one higher than the standard algorithm
       */

       /* round 1 */

       RUN Round1(INPUT-OUTPUT A, B, C, D, X[1],   7,  -680876936).
       RUN Round1(INPUT-OUTPUT D, A, B, C, X[2],  12,  -389564586).
       RUN Round1(INPUT-OUTPUT C, D, A, B, X[3],  17,   606105819).
       RUN Round1(INPUT-OUTPUT B, C, D, A, X[4],  22, -1044525330).
       RUN Round1(INPUT-OUTPUT A, B, C, D, X[5],   7,  -176418897).
       RUN Round1(INPUT-OUTPUT D, A, B, C, X[6],  12,  1200080426).
       RUN Round1(INPUT-OUTPUT C, D, A, B, X[7],  17, -1473231341).
       RUN Round1(INPUT-OUTPUT B, C, D, A, X[8],  22,   -45705983).
       RUN Round1(INPUT-OUTPUT A, B, C, D, X[9],   7,  1770035416).
       RUN Round1(INPUT-OUTPUT D, A, B, C, X[10], 12, -1958414417).
       RUN Round1(INPUT-OUTPUT C, D, A, B, X[11], 17,      -42063).
       RUN Round1(INPUT-OUTPUT B, C, D, A, X[12], 22, -1990404162).
       RUN Round1(INPUT-OUTPUT A, B, C, D, X[13],  7,  1804603682).
       RUN Round1(INPUT-OUTPUT D, A, B, C, X[14], 12,   -40341101).
       RUN Round1(INPUT-OUTPUT C, D, A, B, X[15], 17, -1502002290).
       RUN Round1(INPUT-OUTPUT B, C, D, A, X[16], 22,  1236535329).

       /* round 2 */

       RUN Round2(INPUT-OUTPUT A, B, C, D, X[2],   5,  -165796510).
       RUN Round2(INPUT-OUTPUT D, A, B, C, X[7],   9, -1069501632).
       RUN Round2(INPUT-OUTPUT C, D, A, B, X[12], 14,   643717713).
       RUN Round2(INPUT-OUTPUT B, C, D, A, X[1],  20,  -373897302).
       RUN Round2(INPUT-OUTPUT A, B, C, D, X[6],   5,  -701558691).
       RUN Round2(INPUT-OUTPUT D, A, B, C, X[11],  9,    38016083).
       RUN Round2(INPUT-OUTPUT C, D, A, B, X[16], 14,  -660478335).
       RUN Round2(INPUT-OUTPUT B, C, D, A, X[5],  20,  -405537848).
       RUN Round2(INPUT-OUTPUT A, B, C, D, X[10],  5,   568446438).
       RUN Round2(INPUT-OUTPUT D, A, B, C, X[15],  9, -1019803690).
       RUN Round2(INPUT-OUTPUT C, D, A, B, X[4],  14,  -187363961).
       RUN Round2(INPUT-OUTPUT B, C, D, A, X[9],  20,  1163531501).
       RUN Round2(INPUT-OUTPUT A, B, C, D, X[14],  5, -1444681467).
       RUN Round2(INPUT-OUTPUT D, A, B, C, X[3],   9,   -51403784).
       RUN Round2(INPUT-OUTPUT C, D, A, B, X[8],  14,  1735328473).
       RUN Round2(INPUT-OUTPUT B, C, D, A, X[13], 20, -1926607734).

       /* round 3 */

       RUN Round3(INPUT-OUTPUT A, B, C, D, X[6],   4,     -378558).
       RUN Round3(INPUT-OUTPUT D, A, B, C, X[9],  11, -2022574463).
       RUN Round3(INPUT-OUTPUT C, D, A, B, X[12], 16,  1839030562).
       RUN Round3(INPUT-OUTPUT B, C, D, A, X[15], 23,   -35309556).
       RUN Round3(INPUT-OUTPUT A, B, C, D, X[2],   4, -1530992060).
       RUN Round3(INPUT-OUTPUT D, A, B, C, X[5],  11,  1272893353).
       RUN Round3(INPUT-OUTPUT C, D, A, B, X[8],  16,  -155497632).
       RUN Round3(INPUT-OUTPUT B, C, D, A, X[11], 23, -1094730640).
       RUN Round3(INPUT-OUTPUT A, B, C, D, X[14],  4,   681279174).
       RUN Round3(INPUT-OUTPUT D, A, B, C, X[1],  11,  -358537222).
       RUN Round3(INPUT-OUTPUT C, D, A, B, X[4],  16,  -722521979).
       RUN Round3(INPUT-OUTPUT B, C, D, A, X[7],  23,    76029189).
       RUN Round3(INPUT-OUTPUT A, B, C, D, X[10],  4,  -640364487).
       RUN Round3(INPUT-OUTPUT D, A, B, C, X[13], 11,  -421815835).
       RUN Round3(INPUT-OUTPUT C, D, A, B, X[16], 16,   530742520).
       RUN Round3(INPUT-OUTPUT B, C, D, A, X[3],  23,  -995338651).

       /* round 4 */

       RUN Round4(INPUT-OUTPUT A, B, C, D, X[1],   6,  -198630844).
       RUN Round4(INPUT-OUTPUT D, A, B, C, X[8],  10,  1126891415).
       RUN Round4(INPUT-OUTPUT C, D, A, B, X[15], 15, -1416354905).
       RUN Round4(INPUT-OUTPUT B, C, D, A, X[6],  21,   -57434055).
       RUN Round4(INPUT-OUTPUT A, B, C, D, X[13],  6,  1700485571).
       RUN Round4(INPUT-OUTPUT D, A, B, C, X[4],  10, -1894986606).
       RUN Round4(INPUT-OUTPUT C, D, A, B, X[11], 15,    -1051523).
       RUN Round4(INPUT-OUTPUT B, C, D, A, X[2],  21, -2054922799).
       RUN Round4(INPUT-OUTPUT A, B, C, D, X[9],   6,  1873313359).
       RUN Round4(INPUT-OUTPUT D, A, B, C, X[16], 10, -  30611744).
       RUN Round4(INPUT-OUTPUT C, D, A, B, X[7],  15, -1560198380).
       RUN Round4(INPUT-OUTPUT B, C, D, A, X[14], 21,  1309151649).
       RUN Round4(INPUT-OUTPUT A, B, C, D, X[5],   6,  -145523070).
       RUN Round4(INPUT-OUTPUT D, A, B, C, X[12], 10, -1120210379).
       RUN Round4(INPUT-OUTPUT C, D, A, B, X[3],  15,   718787259).
       RUN Round4(INPUT-OUTPUT B, C, D, A, X[10], 21,  -343485551).

       /* update MD5 registers */
       ASSIGN
         A = A + AA
         B = B + BB
         C = C + CC
         D = D + DD
         .

   END.

   /* convert MD5 registers to hex string from low-order A to high-order D */

   cDigest = hexGet(A) + hexGet(B) + hexGet(C) + hexGet(D).

   /* cleanup and return */

   SET-SIZE(M) = 0.
   RETURN cDigest.
END FUNCTION.

&ENDIF

/* End of _md5.i */


来源:https://stackoverflow.com/questions/25200708/logical-xor-operator-in-progress

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!