Remove and insert characters in the same position

Asked

Viewed 70 times

1

I have the following problem in PHP

I need to remove the characters from a string, and then insert them in the same position. I’m currently doing so, but I’m open to suggestions.

I have an initial string: te12te

I remove the numbers from this string and store the character and position in two arrays:

$stringInicial = "te12te";

//Processo de remoção resulta em:
$arrayCaracteres = ["1", "2"];
$arrayPosicao = [2, 3];
$stringInicial = "tete";

//As letras da string passam por um processo e são alteradas seguindo uma lógica
$stringInicial = "vivi";

//Preciso agora inserir os caracteres na mesma posição

Given this information, I need to insert the removed characters at the beginning, at the same position. That is, the result should be vi12vi

EDIT: The procedure performed is the Playfair cipher, it follows the code that does this procedure:

 for ($i = 0; $i < strlen($plainText); $i += 2) {
    //compute coords
    $x0 = array_search($plainText[$i], $this->matrix) % 5;
    $y0 = intval(array_search($plainText[$i], $this->matrix) / 5);
    $x1 = array_search($plainText[$i + 1], $this->matrix) % 5;
    $y1 = intval(array_search($plainText[$i + 1], $this->matrix) / 5);

    if ($y0 == $y1) {
        //same line
        $encrypted .= $this->matrix[5 * $y0 + (($x0 + 1) % 5)];
        $encrypted .= $this->matrix[5 * $y1 + (($x1 + 1) % 5)];
    } elseif ($x0 == $x1) {
        //same column
        $encrypted .= $this->matrix[5 * (($y0 + 1) % 5) + $x0];
        $encrypted .= $this->matrix[5 * (($y1 + 1) % 5) + $x1];
    } else {
        //line and column are different
        $encrypted .= $this->matrix[(5 * $y0 + $x1)];
        $encrypted .= $this->matrix[(5 * $y1 + $x0)];
    }
 }
  • str_replace("te","vi",$stringInicial; https://ideone.com/cNRiC1

  • This string is not always the same, I used this only to create the example.

  • and what is the pattern

  • is an encryption cipher, and I need to ignore the numbers when encrypting. There is no default for the initial string

  • 1

    Will always be the numbers that will be removed and inserted?

  • so it’s already a pattern

  • @Andersoncarloswoss will always be numbers and special characters ()! $#@etc

  • Is there a better way to describe how this change of letters works? I was thinking here and I couldn’t think of a beautiful way to do it. All of them seemed gambiarras. Who knows it is possible to integrate the two parts and do something better.

  • @Andersoncarloswoss the process is the cipher of Playfair, I edited to try to show how it is

Show 4 more comments

2 answers

1


Whereas the position is each byte and they may not be together you can use two mb_substr.

foreach($arrayPosicao as $index => $posicao){

    $stringAtePosicao = mb_substr($stringInicial, 0, $posicao, '8bit');
    $stringDepoisPosicao = mb_substr($stringInicial, $posicao, null, '8bit');

    $stringInicial = $stringAtePosicao . $arrayCaracteres[$index] . $stringDepoisPosicao;

}

You can compress this into one line, but I think it makes it clearer. First we take the whole string to the position, then we add the content and take the rest of the string to the end.


Upshot:

vi12vi

This also works cm several replacements if necessary, for example:

$stringInicial = "te12te3abc4";

$arrayCaracteres = ['1', '2', '3', '4'];
$arrayPosicao = [2, 3, 6, 10];
$stringInicial = "tete";

$stringInicial = "viviabc";


foreach($arrayPosicao as $index => $posicao){

    $stringChange  = mb_substr($stringInicial, 0, $posicao, '8bit');
    $stringChange .= $arrayCaracteres[$index];
    $stringChange .= mb_substr($stringInicial, $posicao, null, '8bit');

    $stringInicial = $stringChange;

}

echo $stringInicial;

Upshot:

vi12vi3abc4
  • Why use per byte? What is the efficiency of this if the?

  • @Fernandobagno, because it is not known where the position comes from. Consider aç1, what the position of 1? If it is per byte it is 3, if it is UTF8. If the position is per character using utf8, the position is 2. The questioner does not mention as the $arrayPosicao is done, so I deduced that it is per byte and used the mb_* which allows defining another type (if the position is by UTF8 character, just set utf8). The reason to define 8bit is because PHP is "silly", its behavior is changed by mbstring.func_overload and mb_internal_encoding, then define 8bit is for safety.

  • Got it. Thanks for the explanation. In my answer I considered it using str_pos of life.

0

Whereas you will keep the string the same size, you can use substr_replace for that reason:

foreach($arrayCaracteres as $k=>$value) {
    substr_replace($stringInicial, $value, 0, $arrayPosicao[$k]);
}
  • For each position found, make the change during the foreach with the $value and the position array index ($k);
  • The 0 index if the character count is from the first position;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.