Python Forum
mkpw: rewriting in python 3
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
mkpw: rewriting in python 3
#1
i have this command originally written in C that i would like to rewrite in python 3.  anyone want to join in?  it takes a length as the only argument then outputs a candidate password randomly generated with letters, numbers, and special characters.

here is my original C code, untabified:
//-----------------------------------------------------------------------------
// Copyright © 2012 - Phil D. Howard - All rights reserved
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//-----------------------------------------------------------------------------
// license      ISC (BSD)
//-----------------------------------------------------------------------------
// author       Philip Howard
// email        echo L3I2rF5kYaIvnz5ypHO0rz52rF5jLabX|rot13|mimencode -u|rot13
//-----------------------------------------------------------------------------
// This file is best viewed using a fixed spaced font such as Courier and in a
// display at least 144 columns wide.
//-----------------------------------------------------------------------------
// compile      gcc -O3 -o mkpw mkpw.c && strip mkpw && ldd mkpw && ls -dl mkpw
//-----------------------------------------------------------------------------

#include <alloca.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define ARCHBITS        64
#define ARCHINT_T       uint64_t

#define DEFPWLEN        10
#define MAXPWLEN        32768
#define MINPWLEN        6

static unsigned long long       limit   = 5631351470947265625ULL;       /* 75^10 */
// static unsigned long         maxrn   = 33554432;
static unsigned long            maxrn   = 65536;

static char     rname[]         = "/dev/urandom";
static char     chset[75]       = "%&+,-./0123456789:=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
static char     class[75]       = "000000011111111110000333333333333333333333333330222222222222222222222222220";

static int      maxcount[4]     = { MAXPWLEN, MAXPWLEN, MAXPWLEN, MAXPWLEN };
static int      mincount[4]     = { 1, 1, 1, 20 };

int
main ( int argc, char ** argv )
{
    union {
        ARCHINT_T       number  ;
        unsigned char   buffer  [ARCHBITS/8];
    } numbuf;

    FILE                *rfile          ;
    char                *pw,*ptr,*pn,*pwend     ;
    unsigned long       cntrn           ;
    int                 counts[4]       ;
    int                 len,n,r         ;

    unsigned char       table   [256];

    //-- Get our own program name.
    pn = argv[0];
    while ( * pn ) ++ pn;
    while ( pn > argv[0] && * pn != '/' ) -- pn;
    if ( * pn == '/' ) ++ pn;

    //-- Get desired password length.
    len = DEFPWLEN;
    if ( -- argc && * ++ argv ) {
        len = strtoul( * argv, NULL, 0 );
        if ( len > MAXPWLEN ) len = MAXPWLEN;
        if ( len < MINPWLEN ) len = MINPWLEN;
    }

    //-- Open the random bit source.
    rfile = fopen( rname, "r" );
    if ( ! rfile ) {
        fprintf( stderr, "%s: unable to open \"%s\" to read random bits: %s\n", pn, rname, strerror( errno ) );
        return 1;
    }

    //-- Build character class lookup table.
    memset( table, 0, sizeof table );
    for ( n = 0; n < 75; ++ n ) {
        table[ chset[n] ] = class[n] - '0';
    }

    //-- Convert character class lookup to binary values.
    for ( ptr = class; * ptr; ++ ptr ) * ptr = * ptr - '0';

    //-- Get automatic space sized for the requested length.
    pw = alloca( len + 1 );
    if ( ! pw ) {
        fprintf( stderr, "%s: unable to allocate %llu bytes for password string\n", pn,
                 (unsigned long long) ( len + 1 ) );
        return 1;
    }
    pwend = pw + len;
    * pwend = 0;

    cntrn = 0;

    //-- Repeat until a password that meets requirements is generated.
    for (;;) {

        counts[0] = 0;
        counts[1] = 0;
        counts[2] = 0;
        counts[3] = 0;

        //-- Repeat until a password of sufficient length is generated.
        for ( ptr = pw; ptr < pwend; ) {

            //-- Check for max tries.
            if ( ++ cntrn > maxrn ) {
                fprintf( stderr, "%s: exceeded %lu random values without valid password\n", pn, maxrn );
                return 1;
            }

            //-- Read random bits
            r = fread( numbuf.buffer, 1, ARCHBITS/8, rfile );
            if ( feof( rfile ) ) {
                fprintf( stderr, "%s: unexpected EOF from \"%s\"\n", pn, rname );
                fclose( rfile );
                return 1;
            }
            if ( r < 8 ) {
                fprintf( stderr, "%s: error reading 8 bytes from \"%s\": %s\n", pn, rname, strerror( errno ) );
                fclose( rfile );
                return 1;
            }

            //-- Reject values that can lead to an uneven distribution of characters.
            if ( numbuf.number > limit ) continue;

            //-- Encode some characters.
            for ( n = 0; ptr < pwend && n < (ARCHBITS/6); ++ ptr, ++ n ) {
                r = numbuf.number % 75ULL;
                numbuf.number /= 75ULL;
                *ptr = chset[r];
                counts[ table[ *ptr ] ]++;
            }
        }

//      printf( "%2u %2u %2u %2u %s\n", counts[0], counts[1], counts[2], counts[3], pw );

        if ( counts[0] >= mincount[0] && counts[0] <= maxcount[0] &&
             counts[1] >= mincount[1] && counts[1] <= maxcount[1] &&
             counts[2] >= mincount[2] && counts[2] <= maxcount[2] &&
             counts[3] >= mincount[3] && counts[3] <= maxcount[3] ) break;
    }

    fclose( rfile );
    puts( pw );

    return 0;
}
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Messages In This Thread
mkpw: rewriting in python 3 - by Skaperen - Mar-10-2017, 05:33 AM
RE: mkpw: rewriting in python 3 - by varung1985 - Mar-16-2017, 10:07 AM
RE: mkpw: rewriting in python 3 - by Skaperen - Mar-17-2017, 05:49 AM
RE: mkpw: rewriting in python 3 - by Ofnuts - Mar-16-2017, 01:01 PM
RE: mkpw: rewriting in python 3 - by wavic - Mar-17-2017, 08:13 AM
RE: mkpw: rewriting in python 3 - by Larz60+ - Mar-17-2017, 01:37 PM
RE: mkpw: rewriting in python 3 - by Skaperen - Mar-18-2017, 02:23 AM
RE: mkpw: rewriting in python 3 - by nilamo - Mar-17-2017, 06:55 PM
RE: mkpw: rewriting in python 3 - by snippsat - Mar-17-2017, 07:38 PM
RE: mkpw: rewriting in python 3 - by nilamo - Mar-17-2017, 07:42 PM
RE: mkpw: rewriting in python 3 - by wavic - Mar-18-2017, 11:28 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Rewriting an applications in Python falsedmitri 4 3,001 Jun-03-2019, 01:42 PM
Last Post: heiner55

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020