Home > Software engineering >  Explode a string where the explode condition is bunch of specific characters
Explode a string where the explode condition is bunch of specific characters

Time:12-09

I'm looking for a way to explode a string. For example I have the following string: (we don't count the beggining - 0x)

0xa9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000054368

which is actually a ETH transaction input. I need to explode this string to 3 parts. Imagine 1 bunch of zeros is actually a single space and these spaces define the gates where the string should be exploded.

How can I do that?

CodePudding user response:

preg_split()

This function uses a regular expression to split a string.
So in this example at two or more 0 in a row:

$arr = preg_split('/[0]{2,}/', $string);

print_r($arr);
echo PHP_EOL;

This will output the following:

Array
(
    [0] => a9059xbb
    [1] => fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d
    [2] => 54368
)

Be aware that you will have problems if a message itself has a 00 in it. Assuming it is used as a null-byte for "end of string", this will not happen, though.

preg_match()

This is an example using regular expressions. You can split at arbitrary points.

$string = 'a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000054368';

print_r($string);
echo PHP_EOL;

$res = preg_match('/(.{4})(.{32})(.{32})/', $string, $matches);

print_r($matches);
echo PHP_EOL;

This outputs:

a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000054368
Array
(
    [0] => a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199a
    [1] => a905
    [2] => 9xbb000000000000000000000000fc7a
    [3] => 5f48a1a1b3f48e7dcb1f23a1ea24199a
)

As you can see /(.{4})(.{32})(.{32})/ will find 4 bytes, then 32 and after that 32 again. Capturing groups are made with () around what you want to find. They appear in the $matches array (0 is always the whole string found).

In case you want to ignore certain parts you can express that as well:

/(.{4})9x(.{32}).{4}(.{32})/

This changes the found string:

Array
(
    [0] => a9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d000
    [1] => a905
    [2] => bb000000000000000000000000fc7a5f
    [3] => a1b3f48e7dcb1f23a1ea24199af4d000
)

Links

PHP documentation for the mentioned functions:
https://www.php.net/manual/en/function.preg-split.php
https://www.php.net/manual/en/book.pcre.php

Play around with the second regular expression using this demo:
https://regex101.com/r/pfZtH8/1

CodePudding user response:

If you will always explode them at the same points (4 bytes(8 hexadecimal digits), 32 bytes(64 hexadecimal digits), 32 bytes(64 hexadecimal digits)), you could use substr().

$input = "0xa9059xbb000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d00000000000000000000000000000000000000000000000000000000000054368";
$first = substr($input,2,8);
$second = substr($input,10,64);
$third = substr($input,74,64);

print_r($first);
print "<br>";
print_r($second);
print "<br>";
print_r($third);
print "<br>";

this outputs:

a9059xbb
000000000000000000000000fc7a5f48a1a1b3f48e7dcb1f23a1ea24199af4d0
0000000000000000000000000000000000000000000000000000000000054368
  • Related