Get parameters from hex string with defined lengths in php - php

How to get the 7 variables from this string "c0dbdc000081aa02000000000001c0", defining lengths for each one, some times it comes with voids in Zeros.
Definition to get the data from string:
0xc0->[SLIP Start char:C0]
0xdb,0xdc[C0]->Flag|Version:c,0
0x00->Reserved:0
0x00,0x81->Packet length:129
0xaa,0x02->Packet command:AA02[hex]
0x00,0x00->CRC check:0[hex]
0x00,0x00,0x00,0x01->Serial number:1
0xc0->[SLIP End char:C0]
Example: this are 3 strings with the same data, but 2 of them are shorter in the "Packet length" value, they dont have the 2 leading zeros. (added some spacing to show the missing zeros)
"c0000000 9aaa02000000000029c0"
"c0000000 85aa0200000000000ac0"
"c0dbdc000081aa02000000000001c0"
The code i have works with the last one, but the first ones will get messed up because of missing Zeros. Any ideas on how to manage this?
$inputSample = "C0DBDC000081AA02000000000001C0";
$header = array(
"start" => 2,
"flagVersion" => 4,
"reserved" => 2,
"packetLenght" => 4,
"packetCommand" => 4,
"CRCcheck" => 4,
"serialNumber" => 8,
"end" => 2
);
print_r(ParseIrregularString($inputSample, $header));
function ParseIrregularString($string, $lengths) {
$parts = array();
foreach ($lengths as $StringKey => $position) {
$parts[$StringKey] = substr($string, 0, $position);
$string = substr($string, $position);
}
return $parts;
}
Good Result "C0DBDC000081AA02000000000001C0"
Array
(
[start] => C0
[flagVersion] => DBDC
[reserved] => 00
[packetLenght] => 0081
[packetCommand] => AA02
[CRCcheck] => 0000
[serialNumber] => 00000001,
[end] => C0
)
Bad Result "c00000009aaa02000000000029c0"
Array
(
[start] => c0
[flagVersion] => 0000
[reserved] => 00
[packetLenght] => 9aaa
[packetCommand] => 0200
[CRCcheck] => 0000
[serialNumber] => 000029c0
[end] =>
)

Related

Group rows of data by column value then store nested data, first and last occurrences, and counts within each group

I am trying to split an array of space-delimited strings, group by a particular column, then store the data within each group in a more convenient structure.
Sample data:
$dataArray = [
0 => "AAAAA 2023 01 25 01:04:00 ID:20fjrjeZZ",
1 => "AAAAA 2023 01 25 01:18:08 ID:13454B43A",
2 => "AAAAA 2023 01 25 02:00:02 ID:18f5hjeWe",
3 => "AAAAA 2023 01 25 04:10:13 ID:13454B43A",
4 => "BBBBB 2023 01 25 01:44:10 ID:Xj74320fj",
5 => "BBBBB 2023 01 25 07:08:58 ID:13454B43A",
6 => "BBBBB 2023 01 25 08:40:52 ID:Ftzkk800Y",
7 => "BBBBB 2023 01 25 14:10:13 ID:18f5hjeWe"
];
I split the rows on the space with:
$lines = explode(' ', $dataArray);
Then I want to push the individual parts (AAAA, 2023, 01, ...) into an array.
foreach($dataArray as $parts){
$spotArray[] = $parts[$parts][0];
$yearArray[] = $parts[$parts][1];
// ...
}
Then build a new structure with the new array parts:
foreach($dataArray as $key => $value){
$desiredArray[] = $spotArray[["user"[$yearArray[$hourArray]]], "first"[/** ... */]];
//...
}
Expected result:
$desiredArray = [
"AAAAA" => [
"user" => [
"ID:20fjrjeZZ" => ["01:04:00"],
"ID:13454B43A" => ["01:18:08", "04:10:12"],
"ID:18f5hjeWe" => ["02:00:02"]
],
"first" => "01:04:00",
"last" => "04:10:12",
"totaUser" => 3,
"totalAccess" => 4
],
"BBBBB" => [
"user" => [
"ID:Xj74320fj" => ["01:44:10"],
"ID:13454B43A" => ["07:08:58"],
"ID:Ftzkk800Y" => ["08:40:52"],
"ID:18f5hjeWe" => ["14:10:13"]
],
"first" => "01:44:10",
"last" => "14:10:13",
"totaUser" => 4,
"totalAccess" => 4
]
];
It is not at all necessary to run two loops.
Parse the space-delimited strings in your array and build/overwrite/sum as you iterate.
Code: (Demo)
$result = [];
foreach ($dataArray as $row) {
[$group, $y, $m, $d, $t, $id] = explode(' ', $row);
$result[$group]['user'][$id][] = $t; // accumulate nested elements
$result[$group]['first'] ??= $t; // only store the first occurrence
$result[$group]['last'] = $t; // keep overwriting each time
$result[$group]['totaluser'] = count($result[$group]['user']); // count what is accumulated
$result[$group]['totalAccess'] = ($result[$group]['totalAccess'] ?? 0) + 1; // increment
}
var_export($result);
You can even safely remove the unused $y, $m, and $d declarations if you wish. (Demo)
Output (from either snippet)
array (
'AAAAA' =>
array (
'user' =>
array (
'ID:20fjrjeZZ' =>
array (
0 => '01:04:00',
),
'ID:13454B43A' =>
array (
0 => '01:18:08',
1 => '04:10:13',
),
'ID:18f5hjeWe' =>
array (
0 => '02:00:02',
),
),
'first' => '01:04:00',
'last' => '04:10:13',
'totaluser' => 3,
'totalAccess' => 4,
),
'BBBBB' =>
array (
'user' =>
array (
'ID:Xj74320fj' =>
array (
0 => '01:44:10',
),
'ID:13454B43A' =>
array (
0 => '07:08:58',
),
'ID:Ftzkk800Y' =>
array (
0 => '08:40:52',
),
'ID:18f5hjeWe' =>
array (
0 => '14:10:13',
),
),
'first' => '01:44:10',
'last' => '14:10:13',
'totaluser' => 4,
'totalAccess' => 4,
),
)
You can find the answer to your question here
<?php
$dataArray = [
0 => "AAAAA 2023 01 25 01:04:00 ID:20fjrjeZZ",
1 => "AAAAA 2023 01 25 01:18:08 ID:13454B43A",
2 => "AAAAA 2023 01 25 02:00:02 ID:18f5hjeWe",
3 => "AAAAA 2023 01 25 04:10:13 ID:13454B43A",
4 => "BBBBB 2023 01 25 01:44:10 ID:Xj74320fj",
5 => "BBBBB 2023 01 25 07:08:58 ID:13454B43A",
6 => "BBBBB 2023 01 25 08:40:52 ID:Ftzkk800Y",
7 => "BBBBB 2023 01 25 14:10:13 ID:18f5hjeWe"
];
$finalArr = array();
$count_arr = array();
$count_arr1 = array();
foreach($dataArray as $parts){
$lines = explode(' ', $parts);
$finalArr[$lines[0]]['user'][$lines[5]][] = $lines[4];
$count_arr1[$lines[0]]['user'][$lines[5]] = $lines[4];
$count_arr[$lines[0]][] = 1;
}
foreach($finalArr as $key => $parts){
$finalArr[$key]['first'] = reset($count_arr1[$key]['user']);
$finalArr[$key]['last'] = end($count_arr1[$key]['user']);
$finalArr[$key]['totaUser'] = count($finalArr[$key]['user']);
$finalArr[$key]['totalAccess'] = count($count_arr[$key]);
}
print_r($finalArr);

How do i find the occurence of words of particular number

Hello guys I have a small question that suppose I have a string as
"Hello My name is XYZ"
Now I know I can find the length of the words as "Hello" has 5 characters and "My" has 2 characters. By using following code
$text = file_get_contents('text.txt'); // $text = 'Hello my name is XYZ';
$words = str_word_count($text, 1);
$wordsLength = array_map(
function($word) { return mb_strlen($word, 'UTF-8'); },
$words
);
var_dump(array_combine($words, $wordsLength));
But what if i want to find that the number of words with length 1 is 0. The number of words with lengths 2 is 2. The number of words with length 3 is 1 and so on till number of length 10
Note- I am considering the word length till there is a space Suppose there is a date in the data like 20.04.2016 so it should show me that the number is words with length 10 is 1.
and one more thing how do I find the average length for the words in the string.
Thank you in advance
If you use array_count_values() on the $wordsLength array it will give a count of the string lengths there are. If you use this and a template array (created using array_fill()) with the elements 1-10 and a value of 0. You will get a list of all of the word counts...
$counts = array_replace(array_fill(1, 9, 0),
array_count_values($wordsLength));
will give...
Array
(
[1] => 0
[2] => 2
[3] => 1
[4] => 1
[5] => 1
[6] => 0
[7] => 0
[8] => 0
[9] => 0
)
Hi try this it works on the date and special chars,emojis
$text = 'Hello 20.04.2016 🚩 my face😘face is XYZ';
$words =preg_split('/\s+/', $text);
$wordsLength = array_map(
function($word) { return mb_strlen($word, 'UTF-8'); } ,$words);
print_r($words);
//Get Average word Length
$avg=round(array_sum($wordsLength)/count($words),1);
//print Avg
print($avg);
?>
(Demo)
$text = ' Hello 20.04.2016 🚩 my incredibleness face😘face is XYZ ';
Generate array of continuous visible characters
$words = preg_split('/\s+/', $text, 0, PREG_SPLIT_NO_EMPTY);
array (
0 => 'Hello',
1 => '20.04.2016',
2 => '🚩',
3 => 'my',
4 => 'incredibleness',
5 => 'face😘face',
6 => 'is',
7 => 'XYZ',
)
Replace visible strings with their multibyte length notice the simpler syntax
$wordsLength = array_map('mb_strlen', $words);
array (
0 => 5,
1 => 10,
2 => 1,
3 => 2,
4 => 14,
5 => 9,
6 => 2,
7 => 3,
)
Group and count lengths
$lengthCounts = array_count_values($wordsLength);
array (
5 => 1,
10 => 1,
1 => 1,
2 => 2,
14 => 1,
9 => 1,
3 => 1,
)
Establish an array of defaults, because $lengthCounts may have gaps
$defaultCounts = array_fill_keys(range(1,10), 0);
array (
1 => 0,
2 => 0,
3 => 0,
4 => 0,
5 => 0,
6 => 0,
7 => 0,
8 => 0,
9 => 0,
10 => 0,
)
Filter the counts to remove elements/counts that are out-of-range
$filteredCounts = array_intersect_key($lengthCounts, $defaultCounts);
array (
5 => 1,
10 => 1,
1 => 1,
2 => 2,
9 => 1,
3 => 1,
)
Overwrite the defaults with found counts to prevent gaps in the output
$gaplessCounts = array_replace($defaultCounts, $filteredCounts);
array (
1 => 1,
2 => 2,
3 => 1,
4 => 0,
5 => 1,
6 => 0,
7 => 0,
8 => 0,
9 => 1,
10 => 1,
)

How to get array value then implode them into new array in PHP

I have an array:
Array
(
[10 - 20] => 3
[20 - 30] => 43
[30 - 40] => 5
[40 - 50] => 1
[50 - 60] => 0
[60 - 70] => 0
)
I want to make new array that will send via json. Now I have result in json like this(thanks for guys below who answered my question):
{"success":true,"data":["3","43","5","1","0","0"]}
I need json to be {"success":true,"data":[3,43,5,1,0,0]}, cause only with that format data show in line chart of highchart
Sorry for my stupid questionThank You
Update
Here's how you can get your response...
$values = array
(
'10 - 20' => 3,
'20 - 30' => 43,
'30 - 40' => 5,
'40 - 50' => 1,
'50 - 60' => 0,
'60 - 70' => 0,
);
$data = array_values($values);
$response = array('sucess' => true, 'data' => $data);
echo json_encode($response);
Use array_values, this can be done like so:
$values = array
(
'10 - 20' => 3,
'20 - 30' => 43,
'30 - 40' => 5,
'40 - 50' => 1,
'50 - 60' => 0,
'60 - 70' => 0,
);
$values = array_values($values);
$data = json_encode($values);
echo data;
Output:
[3,43,5,1,0,0]
You might be new to php, Declaration of associative array should be like below
$arr=array(
'[10 - 20]' => 3,
'[20 - 30]' => 43,
'[30 - 40]' => 5,
'[40 - 50]' => 1,
'[50 - 60]' => 0,
'[60 - 70]' => 0
);
array('Key'=>value,'key2'=> value);
Write forearch/for/ any loop to get the values, This is useful if you want to extract both key and values at the same time
foreach ($arr as $key=>$value) {
echo "$value <br>";
}
If you want to get only values then use array_values($arr)
You need to use array_values.
PHP Array
$arr = array("10 - 20" => 3,
"20 - 30" => 43,
"30 - 40" => 5,
"40 - 50" => 1,
"50 - 60" => 0,
"60 - 70" => 0
);
Array values from the array.
$arr2 = array_values($arr);
print_r($arr2);
Output Array
Array
(
[0] => 3
[1] => 43
[2] => 5
[3] => 1
[4] => 0
[5] => 0
)
If you need only the values as string then use implode.
echo implode(" , ", $arr2);
Result
3 , 43 , 5 , 1 , 0 , 0

PHP - Set first array's values to second array's iterations

I'm trying to make one array set to the iterations of another array. I'm working on a hash algorithm that takes in a user value of the order they want the array. It takes their code and breaks it down into 40 blocks of binary to be converted into hexadecimal. So far I'm able to change the iteration order, but it only takes the last value of the first array and sets as the value for each iteration of the second array.
The first array looks like this (Showing only 10 of the 40 to save space):
Array
(
[0] => 0111
[1] => 1000
[2] => 0110
[3] => 0010
[4] => 0011
[5] => 0001
[6] => 0011
[7] => 0010
[8] => 0011
[9] => 0101
)
The second one is like this:
Array
(
[3] => 0101
[2] => 0101
[1] => 0101
[6] => 0101
[5] => 0101
[4] => 0101
[9] => 0101
[8] => 0101
[7] => 0101
[0] => 0101
)
And here is the PHP code:
$arrayDump = $test->binarySplit($name);
$ordered = array();
$orderKey = array(3, 2, 1, 6, 5, 4, 9, 8, 7, 12, 11, 10, 15, 14, 13, 18, 17, 16, 21, 20, 19, 24, 23, 22, 27, 26, 25, 30, 29, 28, 33, 32, 31, 36, 35, 34, 39, 38, 37, 0);
foreach ($orderKey as $key) {
for ($i = $key; $i < count($arrayDump); $i++) {
$ordered[$key] = $arrayDump[$i];
}
}
The class call above isn't too important for this problem that I can tell. The $arrayDump is the first array; $ordered is the second. As you can tell, the second array changes the iteration to be what I want, but it only contains the last value from the first array. I threw it through a loop to try and get each value, but I'm at a loss. Any help would be appreciated.
You don't need the second loop, try this:
foreach ($orderKey as $key => $value) {
$ordered[$key] = $arrayDump[$value];
}

PHP: Determine number of characters that come before a dash in a string

If I have a bunch of strings like XXX-WYC-5b, where XXX is any value between 1 and 999, how do I determine the length of XXX?
So I might have:
1: 6-WYC-5b
2: 32-WYC-5b
3: 932-W-5b
4: 22-XYQ-5b
5: 914-WYC-5b
And I want it to tell me the length of XXX, so:
1: 1 character
2: 2 characters
3: 3 characters
4: 2 characters
5: 3 characters
I would also like to know the value itself, so:
1: 6
2: 32
3: 932
4: 22
5: 914
I keep thinking there's a way to do this using substr_count() and explode(), but I can't seem to figure it out. Thanks very much for your help.
Use PHP's built-in string position function. Because it starts counting at 0, you don't even have to adjust the output:
$pos = strpos($string, "-");
For the second part, use PHP's substring function:
return substr($string, 0, $pos);
a different approach you may want to try:
<?php
$str[] = '6-WYC-5b';
$str[] = '32-WYC-5b';
$str[] = '932-W-5b';
$str[] = '22-XYQ-5b';
$str[] = '914-WYC-5b';
foreach($str as $v){
$result[] = getval($v);
}
function getval($value){
$seg = explode('-',$value);
return array('int'=>$seg[0],'intlen'=>strlen($seg[0]),'char'=>$seg[1],'charlen'=>strlen($seg[1]),'last'=>$seg[2],'lastlen'=>strlen($seg[2]));
}
print_r($result);
?>
outputs:
Array
(
[0] => Array
(
[int] => 6
[intlen] => 1
[char] => WYC
[charlen] => 3
[last] => 5b
[lastlen] => 2
)
[1] => Array
(
[int] => 32
[intlen] => 2
[char] => WYC
[charlen] => 3
[last] => 5b
[lastlen] => 2
)
[2] => Array
(
[int] => 932
[intlen] => 3
[char] => W
[charlen] => 1
[last] => 5b
[lastlen] => 2
)
[3] => Array
(
[int] => 22
[intlen] => 2
[char] => XYQ
[charlen] => 3
[last] => 5b
[lastlen] => 2
)
[4] => Array
(
[int] => 914
[intlen] => 3
[char] => WYC
[charlen] => 3
[last] => 5b
[lastlen] => 2
)
)

Categories