#!/usr/bin/perl
#=======================================================================
# Password Generator
#=======================================================================

use strict;
use warnings "all";

# Oracle Corporation strongly recommends that you not use quotation
# marks to make passwords case sensitive.

# If you name a password with a quoted identifier, then the name cannot
# contain lowercase letters.

# Nonquoted identifiers must begin with an alphabetic character from
# your database character set. Quoted identifiers can begin with any
# character.
# Nonquoted identifiers can contain only alphanumeric characters from
# your database character set and the underscore (_), dollar sign ($),
# and pound sign (#). Oracle Corporation strongly discourages you from
# using $ and #.

# -> ALNUM + ALNUM, _, $, #
# -> "ALNUM, _, $, #,

# Oracle
# MySQL
# UNIX

# 33 - 96, 123 - 126

#-----------------------------------------------------------------------
sub generatePassword
#-----------------------------------------------------------------------
{
  my ($lMinLength, $lMaxLength, $lLowerBound, $lUpperBound, @lExcludeList) = @_;

  my $lPassword = '';
  my $random;

  # Password length
  my $length = int(rand( $lMaxLength-$lMinLength+1 )) + $lMinLength;

  # Password itself
  while ( length($lPassword) < $length ) {

    $random = int(rand( $lUpperBound-$lLowerBound+1 ) ) + $lLowerBound;

    if ( ($random < $lLowerBound)
      or ($random > $lUpperBound)
      or (&inlist($random, @lExcludeList))
       ) {

      next;
    }
    else {

      $lPassword .= chr($random);
    }
  }
  return($lPassword);
}

#-----------------------------------------------------------------------
sub inlist
#-----------------------------------------------------------------------
{
  my ($value, @array) = @_;

  foreach ( @array ) {

    if ( $value eq $_ ) {

      return 1;
    }
  }
  return 0;
}

#-----------------------------------------------------------------------
# MAIN
#-----------------------------------------------------------------------

print <<EOF;
Content-type: text/html;Charset=utf-8

<html lang="en">

<head>
  <title>Password generator</title>
</head>

<body>

<h1>Password generator</h1>
EOF


my ($lower, $upper);

# Password length 8 - 12 characters
$lower = 8;
$upper = 12;
my $length = int(rand( $upper-$lower+1 ) ) + $lower;

# Password itself
$lower = 33;
$upper = 126;

my $password = "";
while ( length($password) < $length ) {
  my $random = int(rand( $upper-$lower+1 ) ) + $lower;
  if ( ($random >= 33 and $random <= 98) or ($random >= 123 and $random <= 126) ) {

    # nur von sqlplus shell geht nicht
    if ( $random != 44 and $random != 34 and $random != 63 and $random != 38) {
        if ( ($random >= 48 and $random <= 57) or ($random >= 65 and $random <= 90) or ($random >= 35 and $random <= 36) or ($random >= 95 and $random <= 95)) {
      $password .= chr($random);
    }
    }
  }
}

print "<p>Please reload for generating new password.</p>";
print "<p>Password for ORACLE (length (8-12): $length):</p>";
print "<p>ALTER USER xyz IDENTIFIED BY \"$password\";</p>";


print "<p>MySQL Password (ASC(32)-ASC(126) without ASC(32, 39, 92) = CHR(&nbsp;&#039;&#092;))</p>";
print "<p><b>Caution</b>: Password is creatable from within mysql with characters 32, 39 and 92 but not usable from UNIX prompt! Length: 93 characters seems to bee possible.</p>";

print "<p>SET PASSWORD FOR &#039;xyz&#039;&#064;&#039;localhost&#039; = PASSWORD(&#039;"
    . &generatePassword(8, 30, ord(' '), ord('~'), (ord(' '), ord("'"), ord('\\'))) . "&#039;);</p>";

print <<EOF;
</body>

</html>
EOF

#=============================================================== EOF ===
