Given a randomly generated string, how do I convert it to make it URL safe -- and then "un convert" it?
PHP's bin2hex function (see: http://www.php.net/manual/en/function.bin2hex.php) seems to safely convert strings into URL safe characters. The hex2bin function (see: http://www.php.net/manual/en/function.hex2bin.php) is probably not ready yet. The following custom hex2bin function works sometimes:
function hex2bin($hexadecimal_data)
{
$binary_representation = '';
for ($i = 0; $i < strlen($hexadecimal_data); $i += 2)
{
$binary_representation .= chr(hexdec($hexadecimal_data{$i} . $hexadecimal_data{($i + 1)}));
}
return $binary_representation;
}
It only works right if the input to the function is a valid bin2hex string. If I send it something that was not a result of bin2hex, it dies. I can't seem to get it to throw an exception in case something is wrong.
Any suggestions what I can do? I'm not set on using hex2bin/bin2hex. All I need to to be able to convert a random string into a URL safe string, then reverse the process.
What you want to do is URL encode/decode the string:
$randomString = ...;
$urlSafe = urlencode($randomString);
$urlNotSafe = urldecode($urlSafe); // == $randomString
You can use urlencode()/urldecode().
Related
So i need to check if amount of chars from specific set in a string is higher than some number, what a fastest way to do that?
For example i have a long string "some text & some text & some text + a lot more + a lot more ... etc." and i need to check if there r more than 3 of next symbols: [&,.,+]. So when i encounter 4th occurrence of one of these chars i just need to return false, and stop the loop. So i think to create a simple function like that. But i wonder is there any native method in php to do such a thing? But i need some function which will not waste time parsing the string till the end, cuz the string may be pretty long. So i think regexp and functions like count_chars r not suited for that kind of job...
Any suggestions?
I don't know about a native method, I think count_chars is probably as close as you're going to get. However, rolling a custom solution would be relatively simple:
$str = 'your text here';
$chars = ['&', '.', '+'];
$count = [];
$length = strlen($str);
$limit = 3;
for ($i = 0; $i < $length; $i++) {
if (in_array($str[$i], $chars)) {
$count[$str[$i]] += 1;
if ($count[$str[$i]] > $limit) {
break;
}
}
}
Where the data is actually coming from might also make a difference. For example, if it's from a file then you could take advantage of fread's 2nd parameter to only read x number of bytes at a time within a while loop.
Finding the fastest way might be too broad of a question as PHP has a lot of string related functions; other solutions might use strstr, strpos, etc...
Not benchmarked the other solutions but http://php.net/manual/en/function.str-replace.php passing an array of options will be fast. There is an optional parameter which returns the count of replacements. Check that number
str_replace ( ['&','.','+'], '' , $subject , $count )
if ($count > $number ) {
Well, all my thoughts were wrong and my expectations were crushed by real tests. RegExp seems to work from 2 to 7 times faster (with different strings) than self-made function with simple symbol-checking loop.
The code:
// self-made function:
function chk_occurs($str,$chrs,$limit){
$r=false;
$count = 0;
$length = strlen($str);
for($i=0; $i<$length; $i++){
if(in_array($str[$i], $chrs)){
$count++;
if($count>$limit){
$r=true;
break;
}
}
}
return $r;
}
// RegExp i've used for tests:
preg_match('/([&\\.\\+]|[&\\.\\+][^&\\.\\+]+?){3,}?/',$str);
Of course it works faster because it's a single call to native function, but even same code wrapped into function works from 2 to ~4.8 times faster.
//RegExp wrapped into the function:
function chk_occurs_preg($str,$chrs,$limit){
$chrs=preg_quote($chrs);
return preg_match('/(['.$chrs.']|['.$chrs.'][^'.$chrs.']+?){'.$limit.',}?/',$str);
}
P.S. i wasn't bothered to check cpu-time, just was testing walltime measured via microtime(true); of the 200k iteration loop, but it's enough for me.
I need to generate a random 4 character string on each form submission. I got this solution from here.
which is this.
function genTicketString() {
return substr(md5(uniqid(mt_rand(), true)), 0, 4);
}
add_shortcode('quoteticket', 'genTicketString');
But this mostly generates a similar ID! probably if I can add the date & time along with the 4 character, it will fix it.
So how can I add the data & the time to the generated string?
As a direct answer to your question
To generate a pseudo random string, you can use this function :
function getPseudoRandomString($length = 4) {
$base64Chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/';
$result = '';
for ($i = 0; $i < $length; ++$i) {
$result .= $base64Chars[mt_rand(0, strlen($base64Chars) - 1)];
}
return $result;
}
NOTE : This generates a pseudo random string, there is no way to be sure the string is unique.
To get a "more unique" string
first, you should use a longer string : 4 chars is really small : there are only 16 million possibilities with a set of 64 chars.
Then, If you want to add more unicity, you can concatenate a random generated string with the result of uniqid('', true) http://php.net/manual/en/function.uniqid.php
To be sure the string has never been generated
The only way to to be sure the string has never been generated is to save all generated strings in a database and when you generate a new string, you have to check if the string already exists in the database to generate a new one if needed.
The generator function will look like
function generateUniqueString()
do {
$string = generateString();
while (is_in_database($string));
save_in_database($string);
return $string;
}
I used this answer instead with little modifications
function genTicketString() {
$d=date ("d");
$m=date ("m");
$y=date ("Y");
$t=time();
$dmt=$d+$m+$y+$t;
$ran= rand(0,10000000);
$dmtran= $dmt+$ran;
$un= uniqid();
$dmtun = $dmt.$un;
$mdun = md5($dmtran.$un);
$sort=substr($mdun, 0, 6); // if you want sort length code.
$sort=strtoupper($sort);
return $sort;
}
add_shortcode('quoteticket', 'genTicketString');
I have been asked/told to convert a foxpro function to PHP, however I know nothing about foxpro.
PARAMETERS cCkey
LOCAL cKey
cKey = SUBSTR(SYS(2015),2)+PADL(LTRIM(STR(INT(IIF(INT(RAND()*1000000000) = 851390329,RAND(-1),RAND())*1000000),6)),6,"0")
RETURN cKey
Above is the function they are wanting to use in a system that is being built in php to integrate with the foxpro databases.
Some of the functions are familiar from PHP, but others like the "SYS", and "IIF" are not, and being that I know someone on here will be able to take one look at it, and know exactly what it is doing.
Mind helping me out? Thanks in advance.
Sys(2015) is a handy VFP function which returns a value unique to that session of VFP. You can read it here
Iif is inline if-else-endif statement .. like Excel does
Updated
SYS(2015) in PHP ? I don't know .. but if we talking about random string in PHP, you can use this
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
I got that from this link and got the basic idea from this link
About the other part MAYBE like this :
$randomresult = 0
$srandom = ""
If (INT(RAND()*1000000000) = 851390329)
{
$randomresult = int(rand(-1)) * 1000000
}
else
{
$randomresult = int(rand()) * 1000000
}
$srandom=str_pad(ltrim(strval($randomresult),"0")),6,"0",STR_PAD_LEFT)
So, MAYBE we can make the foxpro code like this in PHP :
$cKey = rand_string(10) . str_pad(ltrim(strval($randomresult),"0")),6,"0",STR_PAD_LEFT)
At least you can the idea .....
SYS(2015) Returns a unique 10-character procedure name that begins with an underscore followed by a combination of letters and numbers.
http://msdn.microsoft.com/en-us/library/684by7c1(v=vs.80).aspx
IIF Returns one of two values depending on the value of a logical expression.
http://msdn.microsoft.com/en-us/library/7ttt15k6(v=vs.80).aspx
With this information I think you can at least take a stab at creating a PHP function and then showing some PHP and asking for help if needed.
I'm trying to convert a text string to hexadecimal in php (which sounds trivial enough) but all the conversions I have tried output incorrect data.
The string I need to convert is;
RTP1 •. • A ¥;¥9ÈKJ| %¯ : E~WF 3HxI#Y¥
The correct result is;
525450310120209501022e2095204120030503040ba53b03040ba539c84b041f4a7c1120202025af032020203a20457e0357462033487849230459a52020202020
But I consistently get;
52545031012020e280a201022e20e280a2204120030503040bc2a53b03040bc2a539c3884b041f4a7c1120202025c2af032020203a20457e0357462033487849230459c2a52020202020
The online calculator at http://www.swingnote.com/tools/texttohex.php works on this perfectly - I have emailed the author to request the php source code but have had no answer.
I've tried the following functions without success;
bin2hex($data);
function strToHex($string)
{
$hex='';
for ($i=0; $i < strlen($string); $i++)
{
$hex .= dechex(ord($string[$i]));
}
return $hex;
}
for ($i = 0; $i < strlen($string); $i++) {
echo dechex(ord($string[$i]));
}
and a few others I can no longer find... I'm really at a loss with this so any help will be greatly appreciated!
Thanks!
Matthew
The input string appears to contain utf-8 encoded characters (I say this based on the output). Try converting these characters back into an ASCII/ISO-8859-1 alike format.
$indat = utf8_decode("...");
$hexdata = bin2hex($indat);
I usually just process it one char at a time.
$str = 'My Cool String!';
$hex = '';
$str_ary = str_split($str);
foreach($str_ary as $char)
{
$hex .= dechex(ord($char));
}
echo $hex;
Edit:
Looking at it again, it looks like our code is very similar (didn't notice the code :\ ). I believe Jeff Parker has the right idea in the comment, it might just be a display issue.
This is not about security. It is also not to make it hard to break. I'm looking for a simple algorithm to change a string (a url) in a way it does not resemble the original. The encryption will be done with javascript. Then I want to feed the encrypted string to a PHP function to change it back to the original. Both ends could share a secret key, or the conversions could be key-less and rely on just logic.
The ideal solution
will be simple
will use available javascript functions for encryption
will use available php functions for decryption
will produce encrypted string in way not to resemble the plain text at all
will only use lower-case alphabet characters and numbers in the encrypted string
is not a method widely used like Base64-ing as encryption.
Edit: The last requirement was added after shamittomar's answer.
You can use bitwise XOR in javascript to encode the string and again in PHP to decode it again. I wrote a little Javascript example for you. It works the same in PHP. If you call enc() a second time with the already encoded string, you'll get the original string again.
<html>
<head><title></title></head>
<body>
<script type="text/javascript">
function enc(str) {
var encoded = "";
for (i=0; i<str.length;i++) {
var a = str.charCodeAt(i);
var b = a ^ 123; // bitwise XOR with any number, e.g. 123
encoded = encoded+String.fromCharCode(b);
}
return encoded;
}
var str = "hello world";
var encoded = enc(str);
alert(encoded); // shows encoded string
alert(enc(encoded)); // shows the original string again
</script>
</body>
</html>
In PHP do something like this (caution, this is not tested and it's been a long while since I did PHP):
$encoded = "..."; // <-- encoded string from the request
$decoded = "";
for( $i = 0; $i < strlen($encoded); $i++ ) {
$b = ord($encoded[$i]);
$a = $b ^ 123; // <-- must be same number used to encode the character
$decoded .= chr($a)
}
echo $decoded;
If that's what you want, you can Base64 encode and decode that.
[EDIT]: After OP clarification:
As you do not want widely used methods, here is one rarely used method and that can do it for you by giving output only in LOWERCASE letters and NUMBERS. It is Base32 Encode/Decode. Use the following libraries:
Javascript Base32 Encoder: http://www.tumuski.com/2010/04/nibbler/
PHP Base32 Decoder: https://www.phpclasses.org/package/3484-PHP-Encode-and-decode-data-with-MIME-base-32-encoding.html
If it's not about security, and not about making it hard to break, then how about ROT-13?
//+ Jonas Raoni Soares Silva
//# http://jsfromhell.com/string/rot13 [rev. #1]
String.prototype.rot13 = function(){
return this.replace(/[a-zA-Z]/g, function(c){
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
});
};
...
var s = "My String";
var enc = s.rot13(); // encrypted value in enc
PHP has a native function, str_rot13: http://php.net/manual/en/function.str-rot13.php
$decrypted = str_rot13($_GET['whatever']);
Well I found this page and found Redcully's program not work for me so I thought It happens with all others. finally I got reason and fixed it. Here new code is...
Thanks to Redcully :)
JS function:
function encode(str) {
var encoded = "";
for (i=0; i<str.length;i++) {
var a = str.charCodeAt(i);
var b = a ^ 51; // bitwise XOR with any number, e.g. 123
encoded = encoded+String.fromCharCode(b);
}
return encoded;
}
PHP function:
function decode($encoded) {
$decoded = "";
for( $i = 0; $i < strlen($encoded); $i++ ) {
$b = ord($encoded[$i]);
$a = $b ^ 51; // <-- must be same number used to encode the character
$decoded .= chr($a);
}
return $decoded;
}
How are you planning to implement (hide) the secret in Javascript? IMHO it's not possible.
Edit: OK - not about security.. then just use any baseXX or rot encoding mechanism. But you can't really say one of these algorythms would not be well known...