I am trying write a PHP function that returns a random string of a given length. I wrote this:
<?
function generate_string($lenght) {
$ret = "";
for ($i = 0; $i < $lenght; $i++) {
$ret .= chr(mt_rand(32,126));
}
return $ret;
}
echo generate_string(150);
?>
The above function generates a random string, but the length of the string is not constant, ie: one time it is 30 characters, the other is 60 (obviously I call it with the same length as input every time). I've searched other examples of random string generators, but they all use a base string to pick letters. I am wondering why this method is not working properly.
Thanks!
Educated guess: you attempt to display your plain text string as HTML. The browser, after being told it's HTML, handles it as such. As soon as a < character is generated, the following characters are rendered as an (unknown) HTML tag and are not displayed as HTML standards mandate.
Fix:
echo htmlspecialchars(generate_string(150));
This is the conclusion i reached after testing it a while : Your functions works correctly. It depends on what you do with the randomly generated string. If you are simply echo-ing it, then it might generate somthing like <ck1ask which will be treated like a tag. Try eliminating certain characters from being concatenated to the string.
This function will work to generate a random string in PHP
function getRandomString($maxlength=12, $isSpecialChar=false)
{
$randomString=null;
//initalise the string include lower case, upper case and numbers
$charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//if required special character to include, please set $isSpecialchar= 1 or true
if ($isSpecialChar) $charSet .= "~##$%^*()_±={}|][";
//loop for get specify length character with random characters
for ($i=0; $i<$maxlength; $i++) $randomString .= $charSet[(mt_rand(0, (strlen($charSet)-1)))];
//return the random string
return $randomString;
}
//call the function set value you required to string length default:12
$random8char=getRandomString(8);
echo $random8char;
Source: Generate random string in php
Related
I would like to generate a random string with meaningful word
function randString($length, $charset='abcdefghijklmnopqrstuvwxyz'){
$str = '';
$count = strlen($charset);
while ($length--) {
$str .= $charset[mt_rand(0, $count-1)];
}
return $str;
}
I have used this function but it generate random which has not any meaning in dictionary.
Have you any idea or is it not possible.
Please let me know if you have any idea according or have better solution regarding.
Thanks in advance.
Try this for a random alphanumeric string
function get_random_string($valid_chars, $length) {
$random_string = '';
//Count the number of chars in the valid chars string so we know how many choices we have
$num_valid_chars = strlen($valid_chars);
//Repeat the steps until we've created a string of the right length
for($i=0;$i<$length;$i++) {
//Pick a random number from 1 up to the number of valid chars
$random_pick = mt_rand(1, $num_valid_chars);
//Take the random character out of the string of valid chars
//Subtract 1 from $random_pick because strings are indexed starting at 0, and we started picking at 1
$random_char = $valid_chars[$random_pick-1];
$random_string .= $random_char;
}
return $random_string;
}
As Mark Baker writes in the comments, "meaningful" and "random" are hard to bring together.
However, if you want to show a real word, from a given language, without someone being able to guess in advance what that word will be, you would do it as follows (in pseudocode, don't have time to write it out as PHP):
read list of unique words in language into wordList
generate random integer i, <= length of wordList
return word at position i in wordList
Consider using a password dictionary as the source of your wordlist.
Get a list of words from ASPELL or http://sourceforge.net/projects/wordlist/, importing them into a db table and randomly select one by php :)
Sample query:
SELECT word FROM dictionary order by RAND() LIMIT 1
I am trying to limit the characters of a string. Additionally, if the string is less than the required characters, I want to add padding to it.
function create_string($string, $length) {
$str_len = strlen($string);
if($str_len > $length) {
//if string is greater than max length, then strip it
$str = substr($string, 0, $length);
} else {
//if string is less than the required length, pad it with what it needs to be the length
$remaining = $length-$str_len;
$str = str_pad($string, $remaining);
}
return $str;
}
My input is
"Nik's Auto Salon"
which is 16 characters. The second parameter is 40.
However, This string is returned
"Nik's Auto Salon "
which has only eight characters of padding added onto it. That doesn't seem right.
I also tried this string:
Gold Package Mobile Car Detail
With this input, it returns a string with NO padding added onto it. When that phrase is shorter than the required 45 length I put in the second parameter place.
How can I make this function work according to my specifications?
str_pad doesn't add spaces equal to its second parameter, it pads the string TO the length given in the second parameter. This isn't very clear even in the documentation.
Try this instead (and take out the line where you calculate $remaining):
$str = str_pad($string, $length);
I'm new to Xor encryption, and I'm having some trouble with the following code:
function xor_this($string) {
// Let's define our key here
$key = ('magic_key');
// Our plaintext/ciphertext
$text =$string;
// Our output text
$outText = '';
// Iterate through each character
for($i=0;$i<strlen($text);)
{
for($j=0;$j<strlen($key);$j++,$i++)
{
$outText .= $text{$i} ^ $key{$j};
//echo 'i='.$i.', '.'j='.$j.', '.$outText{$i}.'<br />'; //for debugging
}
}
return $outText;
}
When I run this it works for normal strings, like 'dog' but it only partially works for strings containing numbers, like '12345'.
To demonstrate...
xor_this('dog') = 'UYV'
xor_this('123') = ''
It's also interesting to note that xor_this( xor_this('123') ) = '123', as I expect it to. I'm pretty sure the problem resides somewhere in my shaky understanding of bitwise operators, OR possibly the way PHP handles strings that contain numbers. I'm betting there's someone clever out there that knows exactly what's wrong here. Thanks.
EDIT #1: It's not truly 'encryption'. I guess obfuscation is the correct term, which is what I'm doing. I need to pass a code containing unimportant data from a user without them being able to easily tamper with it. They're completing a timed activity off-line and submitting their time to an online scoreboard via this code. The off-line activity will obfuscate their time (in milliseconds). I need to write a script to receive this code and turn it back into the string containing their time.
How i did it, might help someone ...
$msg = 'say hi!';
$key = 'whatever_123';
// print, and make unprintable chars available for a link or alike.
// using $_GET, php will urldecode it, if it was passed urlencoded
print "obfuscated, ready for url: " . urlencode(obfuscate($msg, $key)) . "\n";
print "deObfuscated: " . obfuscate(obfuscate($msg, $key), $key);
function obfuscate($msg, $key) {
if (empty($key)) return $msg;
return $msg ^ str_pad('', strlen($msg), $key);
}
I think you might have a few problems here, I've tried to outline how I think you can fix it:
You need to use ord(..) to get the ASCII value of a character so that you can represent it in binary. For example, try the following:
printf("%08b ", ord('A')); // outputs "01000001"
I'm not sure how you do an XOR cipher with a multi-byte key, as the wikipedia page on XOR cipher doesn't specify. But I assume for a given key like "123", your key starts "left-aligned" and extends to the length of the text, like this:
function xor_this($text) {
$key = '123';
$i = 0;
$encrypted = '';
foreach (str_split($text) as $char) {
$encrypted .= chr(ord($char) ^ ord($key{$i++ % strlen($key)}));
}
return $encrypted;
}
print xor_this('hello'); // outputs "YW_]]"
Which encrypts 'hello' width the key '12312'.
There's no guarantee that the result of the XOR operation will produce a printable character. If you give us a better idea of the reason you're doing this, we can probably point you to something sensible to do instead.
I believe you are faced with console output and encoding problem rather than XOR-related.
Try to output results of xor function in a text file and see a set of generated characters. I believe HEX editor would be the best choice to observe and compare a generated characters set.
Basically to revert text back (even numbers are in) you can use the same function:
var $textToObfuscate = "Some Text 12345";
var $obfuscatedText = $xor_this($textToObfuscate);
var $restoredText = $xor_this($obfuscatedText);
Based on the fact that you're getting xor_this( xor_this('123') ) = '123', I am willing to guess that this is merely an output issue. You're sending data to the browser, the browser is recognizing it as something which should be rendered in HTML (say, the first half dozen ASCII characters). Try looking at the page source to see what is really there. Better yet, iterate through the output and echo the ord of the value at each position.
Use this code, it works perfect
function scramble($inv) {
$key=342244; // scramble key
$invarr=str_split($inv);
for($index=0;$index<=strlen($inv)-1;$index++) {
srand($key);
$var=rand(0,255);
$res=$res.(chr(ord($var)) ^ chr(ord($invarr[$index])));
$key++;
}
return($res);
}
Try this:
$outText .= (string)$text{$i} ^ (string)$key{$j};
If one of the two operands is an integer, PHP casts the other to an integer and XORs them for a numeric result.
Alternatively, you could use this:
$outText .= chr(ord($text{$i}) ^ ord($key{$j}));
// Iterate through each character
for($i=0; $i<strlen($text); $i++)
{
$outText .= chr(ord($text{$i}) ^ ord($key{$i % strlen($key)))};
}
note: it probably will create some weird characters...
Despite all the wise suggestions, I solved this problem in a much simpler way:
I changed the key! It turns out that by changing the key to something more like this:
$key = 'ISINUS0478331006';
...it will generate an obfuscated output of printable characters.
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!
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.
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];
i think you generate special HTML characters
for example here and iso8859-1 table
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.
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;
}
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.
Yesterday I tracked down a strange bug which caused a website display only a white page - no content on it, no error message visible.
I found that a regular expression used in preg_replace was the problem.
I used the regex in order to replace the title html tag in the accumulated content just before echo´ing the html. The html got rather large on the page where the bug occured (60 kb - not too large) and it seemed like preg_replace / the regex used can only handle a string of certain length - or my regex is really messed up (also possible).
Look at this sample program which reproduces the problem (tested on PHP 5.2.9):
function replaceTitleTagInHtmlSource($content, $replaceWith) {
return preg_replace('#(<title>)([\s\S]+)(<\/title>)#i', '$1'.$replaceWith.'$3', $content);
}
$dummyStr = str_repeat('A', 6000);
$totalStr = '<title>foo</title>';
for($i = 0; $i < 10; $i++) {
$totalStr .= $dummyStr;
}
print 'orignal: ' . strlen($totalStr);
print '<hr />';
$replaced = replaceTitleTagInHtmlSource($totalStr, 'bar');
print 'replaced: ' . strlen($replaced);
print '<hr />';
Output:
orignal: 60018
replaced: 0
So - the function gets a string of length 60000 and returns a string with 0 length. Not what I wanted to do with my regex.
Changing
for($i = 0; $i < 10; $i++) {
to
for($i = 0; $i < 1; $i++) {
in order to decrease the total string length, the output is:
orignal: 6018
replaced: 6018
When I removed the replacing, the content of the page was displayed without any problems.
It seems like you're running into the backtracking limit.
This is confirmed if you print preg_last_error(): it returns PREG_BACKTRACK_LIMIT_ERROR.
You can either increase the limit in your ini file or using ini_set() or change your regular expression from ([\s\S]+) to .*?, which will stop it from backtracking so much.
It thas been said many times before on SO, eg Regex to match the first ending HTMl tag (and probably will be mentioned again) that regexes are not appropriate for HTML because tags are too irregular.
Use DOM functions where they're available.
Backtracking: [\s\S]+ will match ALL available characters, then go backwards through the string looking for the </title>. [^<]+ matches all characters that aren't < and therefore grabs </title> faster.
function replaceTitleTagInHtmlSource($content, $replaceWith) {
return preg_replace('#(<title>)([^<]+)(</title>)#i', '$1'.$replaceWith.'$3', $content);
}
Your regex seems to be a little funny.
([\s\S]+) matches all space and non-space. you should try (.*?) instead.
changing your function works for me:
function replaceTitleTagInHtmlSource($content, $replaceWith) {
return preg_replace('`\<title\>(.*?)\<\/title\>`i', '<title>'.$replaceWith.'</title>', $content);
}
and the problem seems to be you trying to use $1 and $3 to match and