package.xml 0000660 0000773 0000765 00000004335 12653667616 013305 0 ustar gauthierm dusers
Text_Passwordpear.php.netCreating passwords with PHP.Text_Password allows one to create pronounceable and unpronounceable
passwords. The full functional range is explained in the manual at
http://pear.php.net/manual/.Martin Jansenmjmj@php.netyesOlivier Vanhouckeolivierolivier@php.netyes2016-02-011.2.01.2.0stablestableMIT License
* Fixed issues with unpronouncable password generation
* Updated to PHP 5 method syntax
* Improved tests
* Composer support
5.2.11.4.0b12008-11-301.1.11.1.1stablestablePHP License
* Fixed bug #12220: potential problems with global var use (Patch by Christian Weiske)
Text_Password-1.2.0/tests/Text_Password_Test.php 0000770 0000773 0000765 00000014263 12653667616 022115 0 ustar gauthierm dusers
* @copyright 2004-2016 Martin Jansen, Michael Gauthier
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version CVS: $Id$
* @link http://pear.php.net/package/Text_Password
*/
require_once 'Text/Password.php';
/**
* Unit test suite for the Text_Password package
*
* @author Martin Jansen
* @extends PHPUnit_TestCase
* @version $Id$
*/
class Text_Password_Test extends PHPUnit_Framework_TestCase
{
public function testCreate()
{
$password = Text_Password::create();
$this->assertTrue(strlen($password) == 10);
}
public function testCreateWithLength()
{
$password = Text_Password::create(15);
$this->assertTrue(strlen($password) == 15);
}
public function testCreateMultiple()
{
$passwords = Text_Password::createMultiple(3);
$this->_testCreateMultiple($passwords, 3, 10);
}
public function testCreateMultipleWithLength()
{
$passwords = Text_Password::createMultiple(3, 15);
$this->_testCreateMultiple($passwords, 3, 15);
}
public function testCreateNumericWithLength()
{
$password = Text_Password::create(8, 'unpronounceable', 'numeric');
$this->assertRegExp("/^[0-9]{8}$/", $password);
}
public function testCreateFromABCWithLength()
{
$password = Text_Password::create(8, 'unpronounceable', 'a,b,c');
$this->assertRegExp("/^[abc]{8}$/i", $password);
}
public function testCreateAlphabeticWithLength()
{
$password = Text_Password::create(8, 'unpronounceable', 'alphabetic');
$this->assertRegExp("/^[a-z]{8}$/i", $password);
}
public function testCreateUnpronouncableWithAllClasses()
{
$password = Text_Password::create(8, 'unpronounceable', '');
$this->assertRegExp('/^[a-z0-9_#@%&]{8}$/i', $password);
// Make sure all character classes are used at least once.
$this->assertRegExp('/[a-z]/', $password);
$this->assertRegExp('/[A-Z]/', $password);
$this->assertRegExp('/[0-9]/', $password);
$this->assertRegExp('/[_#@%&]/', $password);
}
/**
* Ensures short password generation, where the length is less than the
* number of character classes, works properly
*/
public function testCreateUnpronouncableShortWithAllClasses()
{
$password = Text_Password::create(2, 'unpronounceable', '');
$this->assertRegExp('/^[a-z0-9_#@%&]{2}$/i', $password);
}
// {{{ Test cases for creating passwords based on a given login string
public function testCreateFromLoginReverse()
{
$this->assertEquals("eoj", Text_Password::createFromLogin("joe", "reverse"));
}
public function testCreateFromLoginShuffle()
{
$this->assertTrue(strlen(Text_Password::createFromLogin("hello world", "shuffle")) == strlen("hello world"));
}
public function testCreateFromLoginRotX()
{
$this->assertEquals("tyo", Text_Password::createFromLogin("joe", "rotx", 10));
}
public function testCreateFromLoginRot13()
{
$this->assertEquals("wbr", Text_Password::createFromLogin("joe", "rot13"));
}
public function testCreateFromLoginRotXplusplus()
{
$this->assertEquals("syp", Text_Password::createFromLogin("joe", "rotx++", 9));
}
public function testCreateFromLoginRotXminusminus()
{
$this->assertEquals("swl", Text_Password::createFromLogin("joe", "rotx--", 9));
}
public function testCreateFromLoginXOR()
{
$this->assertEquals("oj`", Text_Password::createFromLogin("joe", "xor", 5));
}
public function testCreateFromLoginASCIIRotX()
{
$this->assertEquals("otj", Text_Password::createFromLogin("joe", "ascii_rotx", 5));
}
public function testCreateFromLoginASCIIRotXplusplus()
{
$this->assertEquals("oul", Text_Password::createFromLogin("joe", "ascii_rotx++", 5));
}
public function testCreateFromLoginASCIIRotXminusminus()
{
$this->assertEquals("uyn", Text_Password::createFromLogin("joe", "ascii_rotx--", 11));
}
// }}}
/**
* Unit test for bug #2605
*
* Actually this method does not implement a real unit test, but
* instead it is there to make sure that no warning is produced
* by PHP.
*
* @link http://pear.php.net/bugs/bug.php?id=2605
*/
public function testBugReport2605()
{
$password = Text_Password::create(7, 'unpronounceable', '1,3,a,Q,~,[,f');
$this->assertTrue(strlen($password) == 7);
}
// {{{ private helper methods
protected function _testCreateMultiple($passwords, $count, $length)
{
$this->assertInternalType("array", $passwords);
$this->assertTrue(count($passwords) == $count);
foreach ($passwords as $password) {
$this->assertTrue(strlen($password) == $length);
}
}
// }}}
}
Text_Password-1.2.0/Text/Password.php 0000770 0000773 0000765 00000042605 12653667616 017675 0 ustar gauthierm dusers
* @author Olivier Vanhoucke
* @copyright 2004-2016 Martin Jansen, Olivier Vanhoucke, Michael Gauthier
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version CVS: $Id$
* @link http://pear.php.net/package/Text_Password
*/
/**
* Number of possible characters in the password
*/
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 0;
/**
* Main class for the Text_Password package
*
* @category Text
* @package Text_Password
* @author Martin Jansen
* @author Olivier Vanhoucke
* @copyright 2004-2016 Martin Jansen, Olivier Vanhoucke, Michael Gauthier
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Release: @package_version@
* @link http://pear.php.net/package/Text_Password
*/
class Text_Password
{
/**
* Create a single password.
*
* @param integer Length of the password.
* @param string Type of password (pronounceable, unpronounceable)
* @param string Character which could be use in the
* unpronounceable password ex : 'ABCDEFG'
* or numeric, alphabetical or alphanumeric.
* @return string Returns the generated password.
*/
public static function create(
$length = 10,
$type = 'pronounceable',
$chars = ''
) {
switch ($type) {
case 'unpronounceable' :
return self::_createUnpronounceable($length, $chars);
case 'pronounceable' :
default :
return self::_createPronounceable($length);
}
}
/**
* Create multiple, different passwords
*
* Method to create a list of different passwords which are
* all different.
*
* @param integer Number of different password
* @param integer Length of the password
* @param string Type of password (pronounceable, unpronounceable)
* @param string Character which could be use in the
* unpronounceable password ex : 'A,B,C,D,E,F,G'
* or numeric, alphabetical or alphanumeric.
* @return array Array containing the passwords
*/
public static function createMultiple(
$number,
$length = 10,
$type = 'pronounceable',
$chars = ''
) {
$passwords = array();
while ($number > 0) {
while (true) {
$password = self::create($length, $type, $chars);
if (!in_array($password, $passwords)) {
$passwords[] = $password;
break;
}
}
$number--;
}
return $passwords;
}
/**
* Create password from login
*
* Method to create password from login
*
* @param string Login
* @param string Type
* @param integer Key
* @return string
*/
public static function createFromLogin($login, $type, $key = 0)
{
switch ($type) {
case 'reverse':
return strrev($login);
case 'shuffle':
return self::_shuffle($login);
case 'xor':
return self::_xor($login, $key);
case 'rot13':
return str_rot13($login);
case 'rotx':
return self::_rotx($login, $key);
case 'rotx++':
return self::_rotxpp($login, $key);
case 'rotx--':
return self::_rotxmm($login, $key);
case 'ascii_rotx':
return self::_asciiRotx($login, $key);
case 'ascii_rotx++':
return self::_asciiRotxpp($login, $key);
case 'ascii_rotx--':
return self::_asciiRotxmm($login, $key);
}
}
/**
* Create multiple, different passwords from an array of login
*
* Method to create a list of different password from login
*
* @param array Login
* @param string Type
* @param integer Key
* @return array Array containing the passwords
*/
public static function createMultipleFromLogin($login, $type, $key = 0)
{
$passwords = array();
$number = count($login);
$save = $number;
while ($number > 0) {
while (true) {
$password = self::createFromLogin($login[$save - $number], $type, $key);
if (!in_array($password, $passwords)) {
$passwords[] = $password;
break;
}
}
$number--;
}
return $passwords;
}
/**
* Helper method to create password
*
* Method to create a password from a login
*
* @param string Login
* @param integer Key
* @return string
*/
protected static function _xor($login, $key)
{
$tmp = '';
for ($i = 0; $i < strlen($login); $i++) {
$next = ord($login[$i]) ^ $key;
if ($next > 255) {
$next -= 255;
} elseif ($next < 0) {
$next += 255;
}
$tmp .= chr($next);
}
return $tmp;
}
/**
* Helper method to create password
*
* Method to create a password from a login
* lowercase only
*
* @param string Login
* @param integer Key
* @return string
*/
protected static function _rotx($login, $key)
{
$tmp = '';
$login = strtolower($login);
for ($i = 0; $i < strlen($login); $i++) {
if ((ord($login[$i]) >= 97) && (ord($login[$i]) <= 122)) { // 65, 90 for uppercase
$next = ord($login[$i]) + $key;
if ($next > 122) {
$next -= 26;
} elseif ($next < 97) {
$next += 26;
}
$tmp .= chr($next);
} else {
$tmp .= $login[$i];
}
}
return $tmp;
}
/**
* Helper method to create password
*
* Method to create a password from a login
* lowercase only
*
* @param string Login
* @param integer Key
* @return string
*/
protected static function _rotxpp($login, $key)
{
$tmp = '';
$login = strtolower($login);
for ($i = 0; $i < strlen($login); $i++, $key++) {
if ((ord($login[$i]) >= 97) && (ord($login[$i]) <= 122)) { // 65, 90 for uppercase
$next = ord($login[$i]) + $key;
if ($next > 122) {
$next -= 26;
} elseif ($next < 97) {
$next += 26;
}
$tmp .= chr($next);
} else {
$tmp .= $login[$i];
}
}
return $tmp;
}
/**
* Helper method to create password
*
* Method to create a password from a login
* lowercase only
*
* @param string Login
* @param integer Key
* @return string
*/
protected static function _rotxmm($login, $key)
{
$tmp = '';
$login = strtolower($login);
for ($i = 0; $i < strlen($login); $i++, $key--) {
if ((ord($login[$i]) >= 97) && (ord($login[$i]) <= 122)) { // 65, 90 for uppercase
$next = ord($login[$i]) + $key;
if ($next > 122) {
$next -= 26;
} elseif ($next < 97) {
$next += 26;
}
$tmp .= chr($next);
} else {
$tmp .= $login[$i];
}
}
return $tmp;
}
/**
* Helper method to create password
*
* Method to create a password from a login
*
* @param string Login
* @param integer Key
* @return string
*/
protected static function _asciiRotx($login, $key)
{
$tmp = '';
for ($i = 0; $i < strlen($login); $i++) {
$next = ord($login[$i]) + $key;
if ($next > 255) {
$next -= 255;
} elseif ($next < 0) {
$next += 255;
}
switch ($next) { // delete white space
case 0x09:
case 0x20:
case 0x0A:
case 0x0D:
$next++;
}
$tmp .= chr($next);
}
return $tmp;
}
/**
* Helper method to create password
*
* Method to create a password from a login
*
* @param string Login
* @param integer Key
* @return string
*/
protected static function _asciiRotxpp($login, $key)
{
$tmp = '';
for ($i = 0; $i < strlen($login); $i++, $key++) {
$next = ord($login[$i]) + $key;
if ($next > 255) {
$next -= 255;
} elseif ($next < 0) {
$next += 255;
}
switch ($next) { // delete white space
case 0x09:
case 0x20:
case 0x0A:
case 0x0D:
$next++;
}
$tmp .= chr($next);
}
return $tmp;
}
/**
* Helper method to create password
*
* Method to create a password from a login
*
* @param string Login
* @param integer Key
* @return string
*/
protected static function _asciiRotxmm($login, $key)
{
$tmp = '';
for ($i = 0; $i < strlen($login); $i++, $key--) {
$next = ord($login[$i]) + $key;
if ($next > 255) {
$next -= 255;
} elseif ($next < 0) {
$next += 255;
}
switch ($next) { // delete white space
case 0x09:
case 0x20:
case 0x0A:
case 0x0D:
$next++;
}
$tmp .= chr($next);
}
return $tmp;
}
/**
* Helper method to create password
*
* Method to create a password from a login
*
* @param string Login
* @return string
*/
protected static function _shuffle($login)
{
$tmp = array();
for ($i = 0; $i < strlen($login); $i++) {
$tmp[] = $login[$i];
}
shuffle($tmp);
return implode($tmp, '');
}
/**
* Create pronounceable password
*
* This method creates a string that consists of
* vowels and consonats.
*
* @param integer Length of the password
* @return string Returns the password
*/
protected static function _createPronounceable($length)
{
$retVal = '';
/**
* List of vowels and vowel sounds
*/
$v = array('a', 'e', 'i', 'o', 'u', 'ae', 'ou', 'io',
'ea', 'ou', 'ia', 'ai'
);
/**
* List of consonants and consonant sounds
*/
$c = array('b', 'c', 'd', 'g', 'h', 'j', 'k', 'l', 'm',
'n', 'p', 'r', 's', 't', 'u', 'v', 'w',
'tr', 'cr', 'fr', 'dr', 'wr', 'pr', 'th',
'ch', 'ph', 'st', 'sl', 'cl'
);
$v_count = 12;
$c_count = 29;
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = $v_count + $c_count;
for ($i = 0; $i < $length; $i++) {
$retVal .= $c[self::_rand(0, $c_count-1)] . $v[self::_rand(0, $v_count-1)];
}
return substr($retVal, 0, $length);
}
/**
* Create unpronounceable password
*
* This method creates a random unpronounceable password
*
* @param integer Length of the password
* @param string Character which could be use in the
* unpronounceable password ex : 'ABCDEFG'
* or numeric, alphabetical or alphanumeric.
* @return string Returns the password
*/
protected static function _createUnpronounceable($length, $chars)
{
$password = '';
// Claases of characters which could be use in the password
$lower = 'abcdefghijklmnopqrstuvwxyz';
$upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$decimal = '0123456789';
$special = '_#@%&';
switch ($chars) {
case 'alphanumeric':
$chars = array($lower, $upper, $decimal);
break;
case 'alphabetical':
$chars = array($lower, $upper);
break;
case 'numeric':
$chars = array($decimal);
break;
case '':
$chars = array($lower, $upper, $decimal, $special);
break;
default:
// Some characters shouldn't be used; filter them out of the
// possible password characters that were passed in. The comma
// character was used in the past to separate input characters and
// remains in the block list for backwards compatibility. Other
// block list characters may no longer be necessary now that
// password generation does not use preg functions, but they also
// remain for backwards compatibility.
$chars = array(trim($chars));
$chars = str_replace(array('+', '|', '$', '^', '/', '\\', ','), '', $chars);
}
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] = 0;
foreach ($chars as $charsItem) {
$GLOBALS['_Text_Password_NumberOfPossibleCharacters'] += strlen($charsItem);
}
// Randomize the order of character classes. This ensures for short
// passwords--less chars than classes--the character classes are
// still random.
shuffle($chars);
// Loop over each character class to ensure the generated password
// contains at least 1 character from each class.
foreach ($chars as $possibleChars) {
// Get a random character from the character class.
$randomCharIndex = self::_rand(0, strlen($possibleChars) - 1);
$randomChar = $possibleChars[$randomCharIndex];
// Get a random insertion position in the current password
// value.
$randomPosition = self::_rand(0, max(strlen($password) - 1, 0));
// Insert the new character in the current password value.
$password = substr($password, 0, $randomPosition)
. $randomChar
. substr($password, $randomPosition);
}
// Join all the character classes together to form the rest of the
// password value. This prevents small character classes from getting
// weighted unfairly in the final password.
$allPossibleChars = implode('', $chars);
// Insert random chars until the password is long enough.
while (strlen($password) < $length) {
// Get a random character from the possible characters.
$randomCharIndex = self::_rand(0, strlen($allPossibleChars) - 1);
$randomChar = $allPossibleChars[$randomCharIndex];
// Get a random insertion position in the current password
// value.
$randomPosition = self::_rand(0, max(strlen($password) - 1, 0));
// Insert the new character in the current password value.
$password = substr($password, 0, $randomPosition)
. $randomChar
. substr($password, $randomPosition);
}
// Truncate the password if it is too long. This can happen when the
// desired length is shorter than the number of character classes.
if (strlen($password) > $length) {
$password = substr($password, 0, $length);
}
return $password;
}
/**
* Gets a random integer between min and max
*
* On PHP 7, this uses random_int(). On older systems it uses mt_rand().
*
* @param integer $min
* @param integer $max
*
* @return integer
*/
protected static function _rand($min, $max)
{
if (version_compare(PHP_VERSION, '7.0.0', 'ge')) {
$value = random_int($min, $max);
} else {
$value = mt_rand($min, $max);
}
return $value;
}
}
?>