Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I was trying to make a URL shortener. Where the give url needs to convert to base 62
I have converted the URL in following but it convert it to random number like 0 or 1sromm8 or 2gs0ygibs
base_convert($shortener->full_url, 10, 36);
How do i convert it to base62 so that every time 5 characters unique name generated.
I use this customized function to convert String to base62 String
function b62e($str) {
if(mb_check_encoding($str, 'ASCII')) {
$out = '';
$len = strlen($str);
for($i=0; $i<$len; $i+=8) {
$chunk = substr($str, $i, 8);
$outlen = ceil( strlen($chunk)*8/6 );// 8bit/char in, 6bits/char out, round up
$hex = bin2hex($chunk);// gmp won't convert from binary, so go via hex
$raw = gmp_strval(gmp_init(ltrim($hex, '0'), 16), 62);// gmp doesn't like leading 0s
$out .= str_pad($raw, $outlen, '0', STR_PAD_LEFT);
}
return $out;
}
return false;// unicode chars not supported
}
function b62d($str) {
if(mb_check_encoding($str, 'ASCII')) {
$out = '';
$len = strlen($str);
for ($i=0; $i<$len; $i+=11) {
$chunk = substr($str, $i, 11);
$outlen = floor( strlen($chunk)*6/8 );// 6bit/char in, 8bits/char out, round down
$raw = gmp_strval(gmp_init(ltrim($chunk, '0'), 62), 16);// gmp doesn't like leading 0s
$pad = str_pad($raw, $outlen * 2, '0', STR_PAD_LEFT);// double output length as as we're going via hex (4bits/char)
$out .= pack('H*', $pad);// same as hex2bin
}
return $out;
}
return false;// unicode chars not supported
}
Demo
All credits go to Marcus Bointon, Thanks to Flash Thunder answer
May you also use obfuscator to prevent users decode variables
function obf62rep($which){// make array before translate string
$rep = [];
$str1 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$str2 = 'GHIJKLMNqrstuvwx01OPQRSTUVWXYZhijklmnop23456789abcdefgyzABCDEF';
if($which){// while obfuscate from-->to
$fr = str_split($str1);
$to = $str2;
}else{// while de-obfuscate to-->from
$fr = str_split($str2);
$to = $str1;
}
foreach($fr as $k=>$v){// make array tr-->to
$rep[$v] = $to[$k];
}
return $rep;
}
function obf62e($str){return strtr($str,obf62rep(1));}// translate string = obf
function obf62d($str){return strtr($str,obf62rep(0));}// translate back = deobf
Demo
And then make it more simple to use, like
function ob62e($str){return obf62e(b62e($str));}// encode base62 + obfuscate
function ob62d($str){return b62d(obf62d($str));}// decode base62 + deobfuscate
Sample usage
echo ob62e('test');
$name = ob62e('jhon');
Related
Hi I need to convert this HEX String 6BE15C3E into a float. I have been using an Arduino to do this in the past and below is the code I would use to convert the HEX into a float on an Arduino.
uint8_t l[] = {0x6b, 0xe1, 0x5c, 0x3e};
float var1;
memcpy(&var1, l, 4);
Serial.println(var1);
The result of the above code is 0.22 which is correct. I've tried using the following code in PHP but I don't get the correct answer:
print_r(hex2float("6BE15C3E"));
function hex2float($strHex) {
$hex = sscanf($strHex, "%02x%02x%02x%02x%02x%02x%02x%02x");
$hex = array_reverse($hex);
$bin = implode('', array_map('chr', $hex));
$array = unpack("dnum", $bin);
return $array['num'];
}
This code is returning 4.56588239954E+211 which seems way off and I'm not sure why. I know the Arduino example has been converted into bytes before hand but I don't know if this needs to be done in PHP.
These are probably not optimal, but I think they work:
function hex2float($strHex) {
$hex = sscanf($strHex, "%02x%02x%02x%02x");
$hex = array_reverse($hex);
$bin = implode('', array_map('chr', $hex));
$array = unpack("f", $bin);
return $array[1];
}
function float2hex($f)
{
$a = unpack("I", pack( "f", $f ));
$w = pack("N", $a[1] );
return bin2hex($w);
}
Tests:
function Test($hex)
{
$f = hex2float($hex);
$hex2 = float2hex($f);
echo "$hex --> $f --> $hex2<br>\n";
}
3f800000 --> 1 --> 3f800000
40000000 --> 2 --> 40000000
bf800000 --> -1 --> bf800000
c0000000 --> -2 --> c0000000
6BE15C3E --> 5.448878216557E+26 --> 6be15c3e
3E5CE16B --> 0.21570365130901 --> 3e5ce16b
Assuming your Arduino and your PHP script are running on different "endian" machines, then the array_reverse() should be removed from hex2float to 'fix' that function. (And float2hex will need some kind of reverse to make it match.)
I have not thought through what it would take to implement conversion between DOUBLE and hex.
Thank you Nigel Ren for fixing this issue. Here is the code used to fix the issue:
function hex2float($strHex) {
$hex = sscanf($strHex, "%02x%02x%02x%02x%02x%02x%02x%02x");
$bin = implode('', array_map('chr', $hex));
$array = unpack("f", $bin);
return $array[1];
}
When inputting 6BE15C3E it returns 0.215... which is the correct answer when rounded up.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
how correctly make on php ?
If set range have small letters -> replace them on big.
length of string - const
number of symbols from 0
set range : [4,6]
Example :
17xG2v9Hj5 -> 17xG2V9Hj5
b7qfK5yte9 -> b7qfK5Yte9
My code :
$m = '17xG2v9Hj5';
$s1 = mb_substr($m, 0, 4); // -> 17xG
$s2 = mb_substr($m, 4, 3); // -> 2v9
$ss = ucwords(strtoupper($s2)); // -> 2V9
$s3 = mb_substr($m, 7,3); // -> Hj5
$my = $s1.$ss.$s3; // -> 17xG2V9Hj5
var_dump($m).'<br/>';
var_dump($s1).'<br/>';
var_dump($s2).'<br/>';
var_dump($ss).'<br/>';
var_dump($s3).'<br/>';
var_dump($my).'<br/>';// ??? ['<br/>'] for [var_dump()]
// don't work;
String : [a-z] and [0-9].
It is possible to make more shortly and faster?
Thanks.
I'm really not sure what you're trying to achieve?
var_dump is typically used for debug purposes, its output will be more readable if wrapped in <pre></pre> tags.
var_dump($my).'<br/>';
Will not actually append '<br/>' to the output of var_dump it will append it the the value returned by var_dump, in this case void
ie.
$out = var_dump($my).'<br/>'; //$out == '<br/>'
If you want to output <br/> after var_dump you must echo it separately.
ie.
var_dump($my);
echo '<br/>';
You may use substr_replace to do this in one round (Assuming range and string-length are fixed)
$in = '17xG2v9Hj5';
var_dump(substr_replace($in, mb_strtoupper(mb_substr($in, 4, 3)), 4, 3));
A multibyte variant of the substr_replace function can be found here
Answer below is based on Revision 1 of the question assuming a more general solution is wanted
Naive solution but should work if I understood your question correctly:
<?php
$in = '17xG2v9Hj5';
$range = [4,6];
var_dump(uc_range($in, $range));
function uc_range($string, array $range) {
if(!is_string($string)) {
throw new InvalidArgumentException('$string is supposed to be a string');
}
$chars = str_split_unicode($string);
foreach(range($range[0], $range[1]) as $keyIndex) {
if(isset($chars[$keyIndex])) {
$chars[$keyIndex] = mb_strtoupper($chars[$keyIndex]);
}
}
return implode("", $chars);
}
// see http://www.php.net/manual/en/function.str-split.php#107658
function str_split_unicode($str, $l = 0) {
if ($l > 0) {
$ret = array();
$len = mb_strlen($str, "UTF-8");
for ($i = 0; $i < $len; $i += $l) {
$ret[] = mb_substr($str, $i, $l, "UTF-8");
}
return $ret;
}
return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}
Using PHP, I'm trying to encode a number into another number that I can decode back to the original number. The encoded string needs to be only numbers and should not contain anything else.
Eg: 10 becomes 573563547892 or something like that.
How can I do something like this in PHP? I tried quite a few encrypt decrypt functions, but none output only numbers.
I looking for something to use in a URL that isn't easy to guess.
So: http://www.me.com/index.PHP?page=20 becomes http://www.me.com/index.PHP?page=5705254782562466
Why not using a mathematicat operation on the original number? like x becomes x * y + z. you would only have to make the reverse operation to get the original number. consider using large enough prime numbers for y and/or z
Quite heavy, but very good encryption, by using ord & chr a bit. While this works, consider other options: just being able to use strings rather then numbers already makes it a lot simpler (base64_encode etc.):
<?php
class Crypter {
private $key = '';
private $iv = '';
function __construct($key,$iv){
$this->key = $key;
$this->iv = $iv;
}
protected function getCipher(){
$cipher = mcrypt_module_open(MCRYPT_BLOWFISH,'','cbc','');
mcrypt_generic_init($cipher, $this->key, $this->iv);
return $cipher;
}
function encrypt($string){
$binary = mcrypt_generic($this->getCipher(),$string);
$string = '';
for($i = 0; $i < strlen($binary); $i++){
$string .= str_pad(ord($binary[$i]),3,'0',STR_PAD_LEFT);
}
return $string;
}
function decrypt($encrypted){
//check for missing leading 0's
$encrypted = str_pad($encrypted, ceil(strlen($encrypted) / 3) * 3,'0', STR_PAD_LEFT);
$binary = '';
$values = str_split($encrypted,3);
foreach($values as $chr){
$chr = ltrim($chr,'0');
$binary .= chr($chr);
}
return mdecrypt_generic($this->getCipher(),$binary);
}
}
$crypt = new Crypter('secret key','12348765');
$encrypted = $crypt->encrypt(1234);
echo $encrypted.PHP_EOL;
//fake missing leading 0
$encrypted = ltrim($encrypted,'0');
echo $encrypted.PHP_EOL;
$decrypted = $crypt->decrypt($encrypted);
echo $decrypted.PHP_EOL;
Result:
057044206104214236155088
57044206104214236155088
1234
I'm looking for a php function which can mask credit card & bank information such as routing number and account numbers. I need to mask many formats, so the existing stack overflow answers don't help me that much.
So for example, if the input is 304-443-2456, the function should return xxx-xxx-2456.
Sometimes the number has dashes, and can be in various lengths.
I'm looking for something generic, that I can extend as needed, preferably a zend framework view helper class.
Some little regex in a function of it own, configuration available:
$number = '304-443-2456';
function mask_number($number, $count = 4, $seperators = '-')
{
$masked = preg_replace('/\d/', 'x', $number);
$last = preg_match(sprintf('/([%s]?\d){%d}$/', preg_quote($seperators), $count), $number, $matches);
if ($last) {
list($clean) = $matches;
$masked = substr($masked, 0, -strlen($clean)) . $clean;
}
return $masked;
}
echo mask_number($number); # xxx-xxx-2456
If the function fails, it will return all masked (e.g. a different seperator, less than 4 digits etc.). Some child-safety build in you could say.
Demo
<?php
function ccmask($cc, $char = '#') {
$pattern = '/^([0-9-]+)([0-9]*)$/U';
$matches = array();
preg_match($pattern, $cc, $matches);
return preg_replace('([0-9])', $char, $matches[1]).$matches[2];
}
echo ccmask('304-443-2456'), "\n";
echo ccmask('4924-7921-9900-9876', '*'), "\n";
echo ccmask('30-43-56', 'x'), "\n";
Outputs:
###-###-2456
****-****-****-9876
xx-xx-56
I use a view helper for that. I tend to avoid Regex though as it always takes me ages to work out what it does, especially if I come back to code after a while.
class Zend_View_Helper_Ccmask
{
public function ccmask($ccNum)
{
$maskArray = explode('-', $ccNum);
$sections = count($maskArray) - 1;
for($i = 0; $i < $sections ; $i++){
$maskArray[$i] = str_replace(array(1,2,3,4,5,6,7,8,9,0), 'x', $maskArray[$i]);
}
return implode('-', $maskArray);
}
}
In your view
echo $this->ccmask('304-443-2456');
//output = xxx-xxx-2456
A good way to look at this is at what won't be masked and outputing xs for everything else. A simple, inexpensive solution is:
function cc_mask( $cc_raw, $unmask_count ){
$cc_masked = '';
for( $i=0; $i < ( strlen( $cc_raw ) - $unmask_count ) ; $i++ ){
//If you want to maintain hyphens and special characters
$char = substr( $cc_raw, $i, 1 );
$cc_masked .= ctype_digit( $char ) ? "*" : $char;
}
$cc_masked .= substr( $cc_raw , -$unmask_count );
return $cc_masked;
}
echo cc_mask("304-443-2456",4);
//Output
***-***-2456
Would be even faster if there was no need to maintain the hyphens and special characters
I need fast way for generating random strings a-Z0-9 in PHP. I've been doing some thinking and testing, this is what I've got so far:
function randStr($length) {
$result = null;
$replace = array('/', '+', '=');
while(!isset($result[$length-1])) {
$result.= str_replace($replace, NULL, base64_encode(mcrypt_create_iv($length, MCRYPT_RAND)));
}
return substr($result, 0, $length);
}
Function seems to be working fast compared to functions which iterate and choose random ASCII value for each char, but I'm concerned with 'quality' of my implementation. I do not know much about cryptography, so I'd like to ask whether this kind of function creates 'good' random values or not.
mcrypt_create_iv seems to return some kind of random binary values, actually used for encrypting/decrypting data with mcrypt library. What is base64_encode effect on this kind of binary data, do I actually decrease entropy, when I base64_encode it?
How does second parameter for mcrypt_create_iv affect my results? php.net manual states that MCRYPT_RAND is 'system random number generator'. Is it OS specific and if so, how good values are created?
This supposed to be secure on most of the systems and fast:
bin2hex(openssl_random_pseudo_bytes($length / 2));
benchmarks (1000000 records, string length 100 chars)
rstr1: 198.93383002281
rstr2: 35.5827729702
rstr3: 6.8811790943146
rstr4: 5.4545040130615
this:: 3.9310231208801
For anyone looking for an updated version of the "best" algorithm:
function randomString($length) {
$result = null;
$replace = array('/', '+', '=');
while(!isset($result[$length-1])) {
$result.= str_replace($replace, NULL, base64_encode(random_bytes($length)));
}
return substr($result, 0, $length);
}
I use the term "best" because it is faster than the random string manipulations of rstr1 and rstr2 and in comparison to the other solutions offers a full spectrum of letters (lower- and uppercased).
From my tests, your function is already very fast, but i managed to get to a faster one, even if it decreases the entropy
fcn time
rstr1: 1.074s (slowest)
rstr2: 0.917s
rstr3: 0.028s (yours)
rstr4: 0.022s (mine)
In my scenario, i needed 1k strings, as fast as possible.
function rstr1($length)
{
// #see http://stackoverflow.com/a/853846/11301
$alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
return substr(str_shuffle(str_repeat($alphabet, $length)), 0, $length);
}
function rstr2($length)
{
// #see http://stackoverflow.com/a/853870/11301
$alphabet='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$str = '';
$count = strlen($alphabet);
while ($length--) {
$str .= $alphabet[mt_rand(0, $count-1)];
}
return $str;
}
function rstr3($length) {
// #see http://stackoverflow.com/q/4757392/11301
$result = null;
$replace = array('/', '+', '=');
while(!isset($result[$length-1])) {
$result.= str_replace($replace, NULL, base64_encode(mcrypt_create_iv($length, MCRYPT_RAND)));
}
return substr($result, 0, $length);
}
function rstr4($length)
{
// uses md5 & mt_rand. Not as "random" as it could be, but it works, and its fastest from my tests
return str_shuffle(substr(str_repeat(md5(mt_rand()), 2+$length/32), 0, $length));
}
// test the functions
for($i=0; $i<1000; $i++){
#$x = rstr1(1024); #
#$x = rstr2(1024); # 0.917s
#$x = rstr3(1024); # 0.028s
#$x = rstr4(1024); # 0.022s
#dlog($x); return;
}
base64_encoding won't decrease entropy, it is just a different representation of the same data.
It is OS specific, but I think the random values created are good enough with this function. Under PHP 5.3 you have to seed the generator beforehand, it can be a problem if you use this code on different servers.
I usually work with this one.
Also I can choose if I don't want certain characters
function rstr5($length = 1) {
return substr(str_shuffle(str_repeat("0123456789abcdefghijklmnopqrstuvwxyz", $length)), 0, $length);
}
This is how I'm doing it, though it's not exactly cryptographic; The Mersenne Twister is fast and reliable, but not the most secure.
function str_rand($chars, $len)
{
$str = '';
for ($max = strlen($chars) - 1, $i = 0; $i < $len; ++$i)
{
$str .= $chars[mt_rand(0, $max)];
}
return $str;
}
$strRand = str_rand('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 40);