Task: Password generator


C++: #include <iostream>
#include <string>
#include <algorithm>
#include <ctime>

const std::string CHR[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", 
                            "0123456789", "!\"#$%&'()*+,-./:;<=>?@[]^_{|}~" };
const std::string UNS = "O0l1I5S2Z";

std::string createPW( int len, bool safe ) {
    std::string pw;
    char t;
    for( int x = 0; x < len; x += 4 ) {
        for( int y = x; y < x + 4 && y < len; y++ ) {
            do {
                t = CHR[y % 4].at( rand() % CHR[y % 4].size() );
            } while( safe && UNS.find( t ) != UNS.npos );
            pw.append( 1, t );
        }
    }
    std::random_shuffle( pw.begin(), pw.end() );
    return pw;
}
void generate( int len, int count, bool safe ) {
    for( int c = 0; c < count; c++ ) {
        std::cout << createPW( len, safe ) << "\n";
    }
    std::cout << "\n\n";
}
int main( int argc, char* argv[] ){
    if( argv[1][1] == '?' || argc < 5 ) {
        std::cout << "Syntax: PWGEN length count safe seed /?\n"
                     "length:\tthe length of the password(min 4)\n"
                     "count:\thow many passwords should be generated\n"
                     "safe:\t1 will exclude visually similar characters, 0 won't\n"
                     "seed:\tnumber to seed the random generator or 0\n"
                     "/?\tthis text\n\n";
    } else {
        int l = atoi( argv[1] ),
            c = atoi( argv[2] ),
            e = atoi( argv[3] ), 
            s = atoi( argv[4] );
        if( l < 4 ) {
            std::cout << "Passwords must be at least 4 characters long.\n\n";
        } else {
            if (s == 0) {
               std::srand( time( NULL ) );
            } else {
               std::srand( unsigned( s ) );
            }
            generate( l, c, e != 0 );
        }
    }
    return 0;   
}



Go: package main

import (
	"crypto/rand"
	"math/big"
	"strings"
	"flag"
	"math"
        "fmt" 
)

var lowercase = "abcdefghijklmnopqrstuvwxyz"
var uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var numbers = "0123456789"
var signs = "!\"#$%&'()*+,-./:;<=>?@[]^_{|}~"
var similar = "Il1O05S2Z"

func check(e error){
	if e != nil {
		panic(e)
	}
}

func randstr(length int, alphastr string) string{
	alphabet := []byte(alphastr)
	pass := make([]byte,length)
	for i := 0; i < length; i++ {
		bign, err := rand.Int(rand.Reader, big.NewInt(int64(len(alphabet))))
		check(err)
		n := bign.Int64()
		pass[i] = alphabet[n]
	}
	return string(pass)
}

func verify(pass string,checkUpper bool,checkLower bool, checkNumber bool, checkSign bool) bool{
	isValid := true
	if(checkUpper){
		isValid = isValid && strings.ContainsAny(pass,uppercase)
	}
	if(checkLower){
		isValid = isValid && strings.ContainsAny(pass,lowercase)
	}
	if(checkNumber){
		isValid = isValid && strings.ContainsAny(pass,numbers)
	}
	if(checkSign){
		isValid = isValid && strings.ContainsAny(pass,signs)
	}
	return isValid
}


func main() {
	passCount := flag.Int("pc", 6, "Number of passwords")
	passLength := flag.Int("pl", 10, "Passwordlength")
	useUpper := flag.Bool("upper", true, "Enables or disables uppercase letters")
	useLower := flag.Bool("lower", true, "Enables or disables lowercase letters")
	useSign := flag.Bool("sign", true, "Enables or disables signs")
	useNumbers := flag.Bool("number", true, "Enables or disables numbers")
	useSimilar := flag.Bool("similar", true,"Enables or disables visually similar characters")
	flag.Parse()

	passAlphabet := ""
	if *useUpper {
		passAlphabet += uppercase
	}
	if *useLower {
		passAlphabet += lowercase
	}
	if *useSign {
		passAlphabet += signs
	}
	if *useNumbers {
		passAlphabet += numbers
	}
	if !*useSimilar {
		for _, r := range similar{
			passAlphabet = strings.Replace(passAlphabet,string(r),"", 1)
		}
	}
	fmt.Printf("Generating passwords with an average entropy of %.1f bits \n", math.Log2(float64(len(passAlphabet))) * float64(*passLength))
	for i := 0; i < *passCount;i++{
		passFound := false
		pass := ""
		for(!passFound){
			pass = randstr(*passLength,passAlphabet)
			passFound = verify(pass,*useUpper,*useLower,*useNumbers,*useSign)
		}
		fmt.Println(pass)
	}
}