|
32 bitų kontrolinės sumos skaičiavimas PROGRESS 4GL priemonėmis
Šis kodas yra pavyzdys, kaip PROGRESS 4GL kalbos priemonėmis
galima manipuliuoti simbolių eilutėmis bitų lygyje. Šis kodas buvo realiai
panaudotas vienoje įmonės pranešimų sistemoje tų pranešimų užtikrintam perdavimui
tarp kelių PROGRESS Application Serverių. Bitų manipuliavimas šiame pavyzdyje
iš tikrųjų yra tik emuliavimas, bet kartais tai daugiau pasiteisina, negu kviesti
išorinę C kalbos programą arba naudotis HLC interfeisu. Tai ypač svarbu, jeigu
norima užtikrinti patikimą PROGRESS tranzakcijų apdorojimą. Žemiau pateiktas
kodas taip pat parodo kaip galima panaudoti loginių kintamųjų masyvus neįprastu
būdu, kad imituoti 'bitų logiką'.
/* checksum.p
*/
PROCEDURE checksum.
/* [LT]
* Paskirtis:
* Skaičiuoja CHAR eilutės 32-bitų kontrolinę sumą ir formuoja
* PROGRESS INT tipo rezultatą. Kadangi INT tipas yra 'signed
* long' - rezultatas gali būti ir neigiamas, priklausomai nuo
* 32-ojo bito. Kontrolinės sumos skaičiavimas C kalbos priemonėmis
* mažiau patrauklus, kadangi reikia iškvietinėti išorinę programą
* (panaudojant INPUT-OUTPUT THROUGH).
*
* Pašaliniai efektai:
* Grąžina checksum kintamojo reikšmę (32-bit checksum).
*/
/* [EN]
* Synopsis:
* Calculates 32-bit checksum of CHAR string. The result is stored
* into variable of INT type. PROGRESS's INT type is a 32-bit signed
* long integer, so the result may be either negative or positive,
* depending on 32'th bit. This module is an attempt not to write
* an external C program, which would be called using
* INPUT-OUTPUT THROUGH.
*
* Returns:
* 32-bit chaecksum, stored in variable of INT type.
*
*
* Author:
* Vladas Saulis (PRODATA) - 1997.
*/
/* Input string, for which we calculate checksum */
DEF INPUT PARAM buf AS CHAR.
/* The resulted checksum */
DEF OUTPUT PARAM checksum AS INT.
DEF VAR c4sum AS INT.
DEF VAR csbits AS LOG EXTENT 32.
DEF VAR c4bits AS LOG EXTENT 32.
DEF VAR bignum AS INT.
DEF VAR buflen AS INT.
DEF VAR k AS INT.
DEF VAR j AS INT.
DEF VAR nbytes AS INT INIT 0.
/* For the sake of sanity */
DO k = 1 TO 32: /* Apnuliname visus bitus */
csbits[k] = false.
END.
buflen = LENGTH(buf).
IF buflen = 0 THEN RETURN.
nbytes = nbytes + buflen.
DO j = 1 TO buflen BY 4:
/* Imame kiekvieną ketvirtuką pranesimo baitų
ir formuojame is jų long INT.
Take every four bytes from the string
and form a long INT from it.
*/
c4sum = 256 * 256 * 256 *
(IF j > buflen THEN 0 ELSE asc(SUBSTRING(buf, j, 1))).
c4sum = c4sum + 256 * 256 *
(IF (j + 1) > buflen THEN 0 ELSE asc(SUBSTRING(buf, j + 1, 1))).
c4sum = c4sum + 256 *
(IF (j + 2) > buflen THEN 0 ELSE asc(SUBSTRING(buf, j + 2, 1))).
c4sum = c4sum +
(IF (j + 3) > buflen THEN 0 ELSE asc(SUBSTRING(buf, j + 3, 1))).
bignum = 256 * 256 * 256 * 64.
/* Skaidome long INT i bitus
* Split long INT to bits
*/
IF c4sum < 0 THEN c4bits[1] = true.
DO k = 2 TO 32:
IF c4sum < bignum THEN c4bits[k] = false.
ELSE DO:
c4sum = c4sum - bignum.
c4bits[k] = true.
END.
bignum = bignum / 2.
END.
DO k = 1 TO 32: /* XOR operation */
csbits[k] = IF csbits[k] = c4bits[k] THEN true ELSE false.
END.
END. /* DO j = 1... */
/* formuojame long INT is bitų
* Form a long INT from the bits
*/
bignum = 1.
checksum = 0.
DO k = 32 TO 1 BY -1:
IF csbits[k] THEN checksum = checksum + bignum.
bignum = 2 * bignum.
END.
END. /* PROC checksum */
|
Jūs galite laisvai naudoti šį kodą Jūsų projektuose su sąlyga,
kad bus nurodyta šio kodo autorystė.
|
|