I'm using an RTF converter and I need 240 as &#U050&#U052&#U048 but Im not to sure how to do this!?!
I have tried using the following function:
function string_to_ascii($string) {
$ascii = NULL;
for ($i = 0; $i < strlen($string); $i++) {
$ascii += "&#U"+str_pad(ord($string[$i]),3,"0",STR_PAD_LEFT);
}
return($ascii);
}
But it still just outputs just the number (e.g. 2 = 50) and ord just makes it go mad.
I've tried echo "-&#U"+ord("2")+"-"; and I get 50416 !?!?
I have a feeling it might have something to do with encoding
I think you're over thinking this. Convert the string to an array with str_split, map ord to all of it, then if you want to format each one, use sprintf (or str_pad if you'd like), like this:
function string_to_ascii($string) {
$array = array_map( 'ord', str_split( $string));
// Optional formatting:
foreach( $array as $k => &$v) {
$v = sprintf( "%03d", $v);
}
return "&#U" . implode( "&#U", $array);
}
Now, when you pass string_to_ascii( '240'), you get back string(18) "&#U050&#U052&#U048".
Just found this:
function to_ascii($string) {
$ascii_string = '';
foreach (str_split($string) as $char) {
$ascii_string .= '&#' . ord($char) . ';';
}
return $ascii_string;
}
here
Related
i have some problem.
i just want my loop to run, but when i try to do it, it fails, it has to increment each letter by a few, but it doesn't take any new letters at all, why is this happening and what is the reason? in c ++ such code would work.
function accum('ZpglnRxqenU') {
// your code
$result = '';
$letters_result = '';
$letter_original = '';
$num_if_str = strlen($s);
$j = 0;
for ( $i=0; $i <= $num_if_str; $i++ )
{
$letter_original = substr($s, $i, $i+1);
$j = 0;
while($j == $i)
{
$letters_result = $letters_result . $letter_original;
$j++;
}
if($i != strlen($s))
{
$letters_result = $letters_result . '-';
}
}
return $letters_result;
}
It returns
- Expected: 'Z-Pp-Ggg-Llll-Nnnnn-Rrrrrr-Xxxxxxx-Qqqqqqqq-Eeeeeeeee-Nnnnnnnnnn-Uuuuuuuuuuu'
Actual : 'Z-----------'
what problem with what PHP code?
There are a number of problems here:
you're using $s but never initialise it
Your call to substr() uses an incorrect value for the length of substring to return
you're inner loop only runs while $i = $j, but you initialise $j to 0 so it will only run when $i is zero, i.e. for the first letter of the string.
There is a simpler way to do this. In PHP you can address individual characters in a string as if they were array elements, so no need for substr()
Further, you can use str_repeat() to generate the repeating strings, and if you store the expanded strings in an array you can join them all with implode().
Lastly, combining ucwords() and strtolower() returns the required case.
Putting it all together we get
<?php
$str = "ZpglnRxqenU";
$output = [];
for ($i = 0;$i<strlen($str);$i++) {
$output[] = str_repeat($str[$i], $i+1);
}
$output = ucwords(strtolower(implode('-',$output)),"-");
echo $output; // Z-Pp-Ggg-Llll-Nnnnn-Rrrrrr-Xxxxxxx-Qqqqqqqq-Eeeeeeeee-Nnnnnnnnnn-Uuuuuuuuuuu
Demo:https://3v4l.org/OoukZ
I don't have much more to add to #TangentiallyPerpendicular's answer as far as critique, other than you've made the classic while($i<=strlen($s)) off-by-one blunder. String bar will have a length of 3, but arrays are zero-indexed [eg: [ 0 => 'b', 1 => 'a', '2' => 'r' ]] so when you hit $i == strlen() at 3, that's an error.
Aside from that your approach, when corrected and made concise, would look like:
function accum($input) {
$result = '';
for ( $i=0, $len=strlen($input); $i < $len; $i++ ) {
$letter = substr($input, $i, 1);
for( $j=0; $j<=$i; $j++ ) {
$result .= $letter;
}
if($i != $len-1) {
$result .= '-';
}
}
return $result;
}
var_dump(accum('ZpglnRxqenU'));
Output:
string(76) "Z-pp-ggg-llll-nnnnn-RRRRRR-xxxxxxx-qqqqqqqq-eeeeeeeee-nnnnnnnnnn-UUUUUUUUUUU"
Also keep in mind that functions have their own isolated variable scope, so you don't need to namespace variables like $letters_foo which can make your code a bit confusing to the eye.
This is the code in lib.php:
<?php
class table {
function __construct($string, $time) {
$out = '<table cellpadding="5">';
$out .= $this->getRow('th', 'Nom., Shuffled String, Lenght');
for ($x = 1; $x <= $time; $x++) {
$shuffledStr = str_shuffle($string); //Maybe this causes the problem
$shuffledStr_len = strlen($shuffledStr);
$out .= $this->getRow('td', $x . ', ' . $shuffledStr . ', ' . $shuffledStr_len);
}
$out .= '</table>';
echo $out;
}
public function getRow($tagName, $contents_list) {
//Variables:
$out = '';
$contents_array = explode(', ', $contents_list);
$contents_number = count($contents_array);
$start_tag = '<' . $tagName . '>';
$end_tag = '</' . $tagName . '>';
// Build
$out .= '<tr>';
for ($i = 0; $i < $contents_number; $i++) {
$out .= $start_tag . $contents_array[$i] . $end_tag;
}
$out .= '</tr>';
return $out;
}
}
?>
And here is index.php:
<?php
require_once 'lib.php';
$string = ''; //My string
$shuffleTimes = 100;
$table = new table($string, $shuffleTimes);
?>
This program gets the a string and the number that you wanna shuffle,
then create a table and returns the number, shuffled string and the length of the shuffle string in each row.
If I set the variable $string to 'Stack Overflow' for instance it'll work correctly (It shuffles this word 100 times randomly, returns all lengths 14 and the length of the ALL shuffled strings are really 14.)
But...
If I add some special character to the variable $string (for example Stack Overflow+_)(*&^%$#{}[]<>#!~./=-) it won't work correctly. That means it returns the lengths 37 But they doesn't have 37 characters!(For example it printed nothing and printed it's lenght 38.
I think it's a bit strange. :(
Why is that?! Which character causes that and how to fix it?
There are multiple issues with your code.
1. getRow() issue :
The problem is in getRow(), where you concat parameters into one string with ,, and then explode by ,. If your string has , inside it, then you will have problems, example: Stack ,test.
2. multibyte issue :
This code doesn't work for multibyte characters. To accomplish that you will need to change function str_shuffle() with function bellow mb_str_shuffle(), and strlen() with mb_strlen().
function mb_str_shuffle($str) {
$tmp = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
shuffle($tmp);
return join("", $tmp);
}
Or some other unicode function that you find in comments on http://php.net/manual/en/function.str-shuffle.php
3. length is ok, but string is missing issue :
This is because you have HTML special chars in your string, like < and >. If string Stack Overflow+_)(*&^%$#{}[]<>#!~./=- is shuffled, and you get something like a#^&/c-_O. instead of a#^&/c-_O.< ~*>)$wevS+{(%}klr[]f=to!#. You should escape special chars with htmlspecialchars() when you output the string.
Sounds like a problem with Encoding.
Have you tried using a function, that handles encoding right?
try this: (copied from PHP Manual)
function unicode_shuffle($string, $chars, $format = 'UTF-8')
{
for($i=0; $i<$chars; $i++)
$rands[$i] = rand(0, mb_strlen($string, $format));
$s = NULL;
foreach($rands as $r)
$s.= mb_substr($string, $r, 1, $format);
return $s;
}
I found some unexpected behavior in my code, so made two examples to demonstrate what was happening and couldn't figure things out from there. What I found was odd to me, and perhaps I'm missing something.
Goal: Create a random string and avoid anything specified in an array.
In the examples below, I have two methods of testing this.
First I have a function that creates a random string from specified characters ($characters) and then I have an array ($avoid) (here with double letters specified) which then loops and informs you if the code worked and it indeed found what was specified in the array.
This seems to work, however then I modified the second function to attempt to generate a new random string if the same trigger happened. This to avoid having a string with anything in the array.
This part doesn't seem to work.. I'm not sure how else to modify it from here, but I must be missing something. Running the code works, but it catches some things and misses other times.. which I wouldn't expect from code.
function getrandom($loopcount)
{
$loopcount++;
$length = 20;
$characters = 'abc';
$string = '';
for ($p = 0; $p < $length; $p++)
$string.= $characters[ mt_rand( 0,strlen($characters) ) ];
$avoid = array(
'aa',
'bb',
'cc'
);
foreach ($avoid as $word)
if ( stripos($string,$word) )
$string = 'Double '.$word.' Detected:'.$string;
return '<h1 style="color:blue;">'.$string.'<h1>';
}
echo getrandom(0);
echo getrandom(0);
echo getrandom(0);
function getrandom2($loopcount)
{
$loopcount++;
$length = 20;
$characters = 'abc';
$string = '';
for ($p = 0; $p < $length; $p++)
$string.= $characters[ mt_rand( 0,strlen($characters) ) ];
$avoid = array(
'aa',
'bb',
'cc'
);
foreach ($avoid as $word)
if ( stripos($string,$word) )
$string = getrandom2($loopcount);
return '<h1 style="color:green;">'.$string.'<h1>';
}
echo getrandom2(0);
echo getrandom2(0);
echo getrandom2(0);
I used this one
function randomToken($length)
{
srand(date("s"));
$possible_charactors = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$string = "";
while(strlen($string)<$length)
{
$string .= substr($possible_charactors, rand()%strlen($possible_charactors),1);
}
return($string);
}
You need to check stripos() with a tripple operator, otherwise your if will interpret the occurrence at position 0 as false (1)
foreach ($avoid as $word){
if ( stripos($string,$word) !== FALSE){
$string = getrandom2($loopcount);
}
}
(1) http://php.net/manual/en/language.operators.comparison.php
The following worked for me:
print gen_rand_str_avoid('abc', 20, array('aa', 'bb', 'cc'));
function gen_rand_str($chars, $length) {
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $str;
}
function gen_rand_str_avoid($chars, $length, array $avoids) {
while (true) {
$str = gen_rand_str($chars, $length);
foreach ($avoids as $avoid) {
if (stripos($str, $avoid) !== false) {
continue 2;
}
}
break;
}
return $str;
}
Initially i had posted a question to find a solution to capitalize every other letter in a string. Thankfully Alex # SOF was able to offer a great solution, however ive been unable to get it to work with an array... To be clear what im trying to do in this case is explode quotes, capitalize every other letter in the array then implode them back.
if (stripos($data, 'test') !== false) {
$arr = explode('"', $data);
$newStr = '';
foreach($arr as $index => $char) {
$newStr .= ($index % 2) ? strtolower($char) : strtoupper($char);
}
$data = implode('"', $arr);
}
Using the anonymous function requires >= PHP 5.3. If not, just make the callback a normal function. You could use create_function(), but it is rather ugly.
$str = '"hello" how you "doing?"';
$str = preg_replace_callback('/"(.+?)"/', function($matches) {
$newStr = '';
foreach(str_split($matches[0]) as $index => $char) {
$newStr .= ($index % 2) ? strtolower($char) : strtoupper($char);
}
return $newStr;
}, $str);
var_dump($str);
Output
string(24) ""hElLo" how you "dOiNg?""
CodePad.
If you want to swap the case, swap the strtolower() and strtoupper() calls.
Is this what you're looking for?
foreach($data as $key => $val)
{
if($key%2==0) $data[$key] = strtoupper($data[$key]);
else $data[$key] = strtolower($data[$key]);
}
Or.... instead of using regular expression you could just not even use the explode method, and go with every other character and capitalize it. Here is an example:
$test = "test code here";
$count = strlen($test);
echo "Count = " . $count . '<br/>';
for($i = 0; $i < $count; $i++)
{
if($i % 2 == 0)
{
$test[$i] = strtolower($test[$i]);
}
else
{
$test[$i] = strtoupper($test[$i]);
}
}
echo "Test = " . $test;
The secret lies in the modulus operator. ;)
Edit: Dang, I just noticed the post above me by Jordan Arsenault already submitted this answer... I got stuck on the regex answer I missed that :-/ sorry Jordan, you were already on point.
My problem is that I've got URL access keys that look like "Bd333333d". I need the string length to be no longer than the original, but may be shorter. I want to convert/obfuscate the duplicate characters in the string and be able to convert them back to the original.
PHP can already do string compression, so why would you want to come up with your own algorithm? See this post for some excellent suggestions of combining gzip compression with urlencoding.
You don't say whether you're storing these strings internally or using them as part of a URL. If it's the former, then this is even easier because you can just store it as the much more compact binary.
This is a good task for preg_replace_callback
$str = 'Bd333333dddd';
function shorten( $str ) {
return preg_replace_callback(
'~(.)\1+~',
function( $matches ) {
return sprintf( '%s.%s', $matches[1], strlen( $matches[0] ) );
},
$str
);
}
UPDATE: Thanks for your help! After doing some work on the hybrid ROT13 concept, I came up with something that works for me. Sorry to be lame and post my own solution, but here it is:
function ROT_by_strpos($s,$type='in'){
$index = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ($n = 0; $n<strlen($index); $n++){
$k[] = substr( $index,$n ,1);
}
if($type == 'out'){
$k = array_reverse($k);
}
$rot = '';
$count = 1;
$len = strlen($s);
for ($n = 0; $n<strlen($s); $n++){
$key_in[] = substr( $s,$n ,1);
}
for ( $i = 0; $i < $len; $i++ ){
$key = array_search($key_in[$i], $k)+1;
if($type == 'in'){
if($key+$i > count($k)){
$rev = $key+$i - count($k);
$new_key = $rev;
}else{
$new_key = $key+$i;
}
}else{
if($key+$i >= count($k)){
$adv = $key+$i - count($k);
$new_key = $adv;
}else{
$new_key = $key+$i;
}
}
$rot .= $k[$new_key];
}
return $rot;
}
This assumes that possible chars are from $index and code string length <= 10 chars long.
Usage:
$key = "Bd333333d";
$in = ROT_by_strpos($key,'in');
$out = ROT_by_strpos($in,'out');
echo "$key - $in - $out"; //Bd333333d - Cf6789ABm - Bd333333d
There's probably a more elegant way to do this, but it does work. Any feedback or improvements would be appreciated if you want to add something. :)