正在进行逻辑XOR运算符

时间:2014-08-08 09:54:53

标签: progress-4gl

是否有XOR运营商正在进行中?
ANDORNOT,因此,我可以像这样编码“XOR”:

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

我只是想知道运营商是否存在(使用其他名称)。

感谢。

2 个答案:

答案 0 :(得分:2)

不幸的是,没有这样的内置运营商正在进行中。 你可以按照你说的方式实现它。

答案 1 :(得分:1)

没有内置XOR。但是你可能会觉得这很有帮助:

   /*  _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 */