geoffs3310
geoffs3310

Reputation: 14008

php outputting strange character

I have the following code to generate a random password string:

<?php
$password = '';

for($i=0; $i<10; $i++) {
$chars = array('lower' => array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'), 'upper' => array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'), 'num' => array('1','2','3','4','5','6','7','8','9','0'), 'sym' => array('!','£','$','%','^','&','*','(',')','-','=','+','{','}','[',']',':','@','~',';','#','<','>','?',',','.','/'));
$set = rand(1, 4); 

switch($set) {
    case 1:
        $set = 'lower';
    break;
    case 2:
        $set = 'upper';
    break;
    case 3:
        $set = 'num';
    break;
    case 4:
        $set = 'sym';
    break;
}
$count = count($chars[$set]);
$digit = rand(0, ($count-1));
$output = $chars[$set][$digit];
$password.= $output;
}
echo $password;
?>

However every now and then one of the characters it outputs will be a capital a with a ^ above it. French or something. How is this possible? it can only pick whats it my arrays!

Upvotes: 1

Views: 396

Answers (6)

Spudley
Spudley

Reputation: 168655

The pound symbol (£) is what is breaking, since it is not part of the basic ASCII character set.

You need to do one of the following:

  • Drop the pound symbol (this will also help people using non-UK keyboards!)
  • Convert the pound symbol to an HTML entity when outputting it to the site (&#pound;)
  • Set your site's character set encoding to UTF-8, which will allow extended characters to be displayed. This is probably the best option in the long run, and should be fairly quick and easy to achieve.

Upvotes: 0

Dutchie432
Dutchie432

Reputation: 29160

As per Jason McCreary, I use this function for such Password Creation

function randomString($length) {
    $characters = "0123456789abcdefghijklmnopqrstuvwxyz" . 
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ$%#^&";

    $string = '';    
    for ($p = 0; $p < $length; $p++) 
        $string .= $characters[mt_rand(0, strlen($characters))];
    return $string;
}   

Upvotes: 0

borrible
borrible

Reputation: 17336

You may be seeing the byte sequence C2 A3, appearing as your capital A with a circumflex followed by a pound symbol. This is because C2A3 is the UTF-8 sequence for a pound sign. As such, if you've managed to enter the UTF-8 character in your PHP file (possibly without noticing it, depending on your editor and environment) you'd see the separate byte sequence as output if your environment is then ASCII / ISO8859-1 or similar.

Upvotes: 0

Jason McCreary
Jason McCreary

Reputation: 72961

Are you sure it is indeed a character not in your array, or is the browser just unable to output? For example your monetary pound sign. Ensure that both PHP, DB, and HTML output all use the same encoding.

On a separate note, your loop is slightly more complicated than it needs to be. I typically see password generators randomize a string versus several arrays. A quick example:

$chars = "abcdefghijkABCDEFG1289398$%#^&";
$pos = rand(0, strlen($chars) - 1);
$password .= $chars[$pos];

Upvotes: 1

shevski
shevski

Reputation: 1022

i think you generate special HTML characters

for example here and iso8859-1 table

Upvotes: 0

Evert
Evert

Reputation: 99525

The only non-ascii character is the pound character, so my guess is that it has to do with this.

First off, it's probably a good idea to avoid that one, as not many people will be able to easily type it.

Good chance that the encoding of your php file (or the encoding set by your editor) is not the same as your output encoding.

Upvotes: 4

Related Questions