• proth01.c

    From Richard Outerbridge@21:1/5 to All on Sun May 14 08:11:47 2017
    In honour of My Mother, God Rest Her Soul.

    Thanks Mom!
    __outer

    /* proth01.c: v2016-02-19 (050) 16:39:54.191 UTC __outer */

    #include <stdlib.h>
    #include <stdio.h>
    #include <ctype.h>
    #include <float.h>
    #include <math.h>
    #include <fenv.h>

    static char COPYRIGHT[] = "proth01.c @Copyright 2009-2016 Graven Imagery"; static char VERSIONID[] = "proth01.c: v2016-02-19 (050) 16:39:54.191 UTC"; static char UNIQUEUID[] = "UUID : [722FDA23-D21B-47AF-895D-5AAA58691980]"; static char *Notice;

    #define MAX_PRC LDBL_DIG /* 53: 15; 64: 18; */
    #define MIN_PRC 9 /* MIN_PRC >= 1e8 */ #define MAX_KEY 1009 /* how madness ends */
    #define MAGIC3 769.0L /* it just is, ok? */
    #define MOD3 0x0300
    #define MAGIC31 7937.0L /* this one is too */
    #define MOD31 0x1f00

    extern int main(int, char **);
    static int crankey331(void), setprc(int), makey(char *);

    static long double Mpr, Mpd, PREX, DPEX;
    static int PRC, DPM, MNK, MNUM, Mod;

    static int crankey331(void) {
    long double copy;
    int ht256;

    fesetround(FE_TOWARDZERO);
    do {
    copy = Mpd * Mpr;
    if( copy >= PREX ) copy /= 10.0L;
    Mpd = truncl(copy);

    if( Mod == MOD31 ) {
    ht256 = (int) fmodl(Mpd, MAGIC31);
    if( ht256 == MOD31 ) Mod = MOD3;
    else break;
    }
    else {
    ht256 = (int) fmodl(Mpd, MAGIC3);
    if( ht256 == MOD3 ) Mod = MOD31;
    else break;
    }
    } while( 1 );
    fesetround(FE_TONEAREST);
    return( ht256 &0xff );
    }

    int main( int argc, char **argv ) {
    int err, c0, key;

    if( (argc < 2) || (argc > 3) ) err = 1;
    else if( argc > 2 ) err = setprc( (int) strtol(argv[1], (char **)NULL, 0) );
    else err = setprc(MAX_PRC);
    if( err == 0 ) err = makey( argv[(argc > 2) ? 2 : 1] );

    if( err != 0 ) {
    fprintf(stderr, "Usage: %s [prc", argv[0]);
    switch( err ) {
    case 1 :
    default:
    fprintf(stderr, " %d-(%d)] key\n", MIN_PRC, MAX_PRC);
    break;
    case 2 :
    fprintf(stderr, ": %d-%d] key - bad precision.\n", MIN_PRC, MAX_PRC);
    break;
    case 3 :
    fprintf(stderr, "] key: %d-%d - key too short.\n", MNK, MAX_KEY);
    break;
    case 4 :
    fprintf(stderr, "] key: %d-%d - invalid key!\n", MNUM, MAX_KEY);
    break;
    }
    (void) exit(err);
    }

    while( (c0 = getc(stdin)) != EOF ) {
    key = crankey331();
    c0 = (0x200 - c0 - key) &0xff;
    putc(c0, stdout);
    }

    Mpr = Mpd = 0.0L;
    Mod = crankey331();
    (void) exit(0);
    }

    static int setprc( int testprc ) {
    if( (testprc > MAX_PRC) || (testprc < MIN_PRC) ) return( 2 );
    PREX = powl(10.0L, (long double) testprc);
    DPEX = PREX/10.0L;
    PRC = testprc;
    DPM = testprc - 1;
    MNK = (testprc*2) + (testprc*2)/10 + 2; /* minimum alphabetic key length */
    MNUM = (testprc*2) + 1; /* minimum literal numeric key */

    Notice = COPYRIGHT; while( *Notice++ != 0 ) { Mpr = Mpd = 0.00L; }
    Notice = VERSIONID; while( *Notice++ != 0 ) { Mpr = Mpd = MAGIC3; }
    Notice = UNIQUEUID; while( *Notice++ != 0 ) { Mpr = Mpd = MAGIC31; }
    return( 0 );
    }

    // #define ZE0 0
    // #define EZ1 1

    #ifdef ZE0
    static char Alpha[27] = "zqxjkvbpygfwmculdrhsnoiate";
    #elif EZ1
    static char Alpha[27] = "etaionshrdlucmwfgypbvkjxqz";
    #else
    static char Alpha[27] = "abcdefghijklmnopqrstuvwxyz";
    #endif

    static int makey( char *keyarg ) {
    int j, k, c0, c1, c2;
    char *copy, key[MAX_KEY], *search, *enuf;
    long double x;

    for( c1 = j = 0, copy = key; *keyarg && (j < MAX_KEY); keyarg++ ) {
    if( isalnum(*keyarg) ) {
    if( isdigit(*keyarg) ) {
    *copy++ = *keyarg - '0';
    c1++;
    }
    else *copy++ = tolower(*keyarg);
    j++;
    }
    *keyarg = 0;
    }
    while( *keyarg ) *keyarg++ = 0;
    if( (j < MNK) && (c1 < MNUM) ) return( 3 );

    enuf = &key[MNK];
    search = Alpha;

    for( c0 = c2 = 0; (c1 < j) && (c2 < MNK) && *search; search++ )
    for( copy = key, k = 0; k < j; k++, copy++ )
    if( *copy == *search ) {
    *copy = c0++ %10;
    c1++;
    if( copy < enuf ) c2++;
    }

    for( copy = key, k = 0; k < 2; k++ ) {
    x = 0.0L;
    for( j = 0; (j < PRC) && ((copy - key) < c1); copy++ )
    if( *copy || (j && (j < DPM)) ) {
    x = (x * 10.0L) + (long double) *copy;
    j++;
    }
    if( x <= DPEX ) return( 4 );
    else if( k ) Mpd = truncl(x);
    else Mpr = truncl(x) / DPEX;
    }

    Mod = (*copy &1) ? MOD31 : MOD3;
    return( 0 );
    }

    /* rwo : port from cyph1.c v2013-04-26 (116) 14:40:11.101 UTC */
    /* rwo : RTZ v2013-05-16 (136) 00:40:27.792 UTC */
    /* rwo : MNK minimizing v2014-02-24 (055) 20:11:21.581 UTC */
    /* rwo : Customize key scheduling v2016-02-19 (050) 16:39:54.191 UTC */
    /* Monaco Regular 10 *************** proth01.c **************************/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)