#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int isValidDESKey(unsigned long long key);

int main() {

    srand(time(0));


    unsigned long long valid[256];
    int sz = 0;
    int oddparity[256];
    for (int i=0; i<256; i++) {

        int cnt = 0;
        for (int j=0; j<8; j++)
            if (i & (1<<j))
                cnt^=1;
        oddparity[i] = cnt;

        if (cnt) valid[sz++] = i;

    }

    for (int i=0; i<20; i++) {


        unsigned long long tmp = 0;
        for (int j=0; j<8; j++) {

            int x = rand()%sz;
            tmp ^= (valid[x] << (8*j));
        }

        int res = isValidDESKey(tmp);
        if (!res) printf("ERROR ON VALID %lld.\n", tmp);

    }
    int err = 0;
    for (int i=0; i<10000; i++) {

        int valid = 1;
        unsigned long long tmp = 0;
        for (int j=0; j<8; j++) {

            unsigned long long x = rand()%256;
            tmp ^= (x << (8*j));

            if (!oddparity[x]) valid = 0;
        }

        int res = isValidDESKey(tmp);
        //printf("%d %d %llu\n", valid, res, tmp);

        if (res != valid) {
            printf("ERROR\n");
            err++;
        }
    }
    printf("num error %d\n", err);

    return 0;
}

/***
int isValidDESKey(unsigned long long key) {

    for (int i=0; i<8; i++) {

        int odd = 0;
        unsigned long long tmp = key & 255;

        for (int j=0; j<8; j++)
            if (tmp&(1<<j))
                odd^=1;

        if (!odd) return 0;

        key >>= 8;
    }

    return 1;
}
***/

int isValidDESKey(unsigned long long key) {

    for (int i=0; i<8; i++) {

        int odd = 0;

        for (int j=0; j<8; j++)
            if (key&(1llu<<(8*i+j)))
                odd^=1;

        if (!odd) return 0;
    }

    return 1;
}
