I am using BEncoded PHP Library to decode the bencoded response from a Bittorrent tracker.
The response of Tracker is:
d5:filesd20:¼€™rÄ2ÞÊþVA .]á^¦d8:completei285e10:downloadedi22911e10:incompletei9eeee
after decoding it using the below code:
require 'bencoded.php';
$be = new BEncoded;
//Response saved in scrape.txt
$data =file_get_contents('scrape.txt');
print_r($be->Decode($data));
the output is:
Array ( [files] => Array ( [¼€™rÄ2ÞÊþVA .]á^¦] => Array ( [complete] => 285 [downloaded] => 22911 [incomplete] => 9 [isDct] => 1 ) [isDct] => 1 ) [isDct] => 1 )
My Problem
my problem in the above output is how to decode those mysterious letters in output.
The link: http://wiki.vuze.com/w/Scrape posted by user3690414 pretty much explains what the different keys stands for.
To interpret the raw bencoded string:
d5:filesd20:¼€™rÄ2ÞÊþVA .]á^¦d8:completei285e10:downloadedi22911e10:incompletei9eeee
you need to understand how bencoding works: https://wiki.theory.org/BitTorrentSpecification#Bencoding
The most essential to know here is that that every entry in a bencoded dictionary is a Key,Value-pair.
Where Key is a byte string
and Value one of the following types: byte string, integer, a list or a dictionary.
With that in mind the raw string can be broken down like this:
d // The first d indicates the start of the Root dictionary
5:files // that has a Key with a 5 byte string name 'files',
d // the value of the 'files'-key is a second dictionary
20:¼€™rÄ2ÞÊþVA .]á^¦ // that has a Key 20 byte = 160 bit big endian SHA1 info-hash
d // the value of that key is a third dictionary
8:complete // that has a Key with a 8 byte string name 'complete',
i285e // the value of that key is a Integer=285
10:downloaded // that has a Key with a 10 byte string name 'downloaded',
i22911e // the value of that key is a Integer=22911
10:incomplete // that has a Key with a 10 byte string name 'incomplete',
i9e // the value of that key is a Integer=9
e // this e indicates the end of the third dictionary
e // this e indicates the end of the second dictionary
e // this e indicates the end of the Root dictionary
Hope this helps to understand the output from 'bencoded.php'.
edit.
If you want to make the 160 bit big endian SHA1 info-hash [¼€™rÄ2ÞÊþVA .]á^¦]
more human readable, I suggest that you output it as 40 byte hex-encoded string:
0xBC801B9D9972C432DECAFE56410F092E5DE15EA6
If you are referring to the mangled key of files array then it's raw infohash - check out the spec:
https://wiki.theory.org/BitTorrentSpecification#Tracker_.27scrape.27_Convention
http://wiki.vuze.com/w/Scrape
Related
We're collecting data from a partner's IoT devices and the data comes encoded in a hex string like 1C000000010028 which contains binary data:
Byte 0 bit 0 Boolean
Byte 0 bit 1 Boolean
Byte 0 bit 2 Boolean
Byte 0 bit 3 Boolean
Byte 0 bits 4-7 UInt4
Bytes 1-2 bits 0-15 UInt16
Byte 3 bits 0-7 UInt8
Bytes 4-5 bits 0-15 UInt16
Byte 6 bits 0-7 UInt8
I have never worked with this kind of data and am wondering how to decode / unpack this in PHP. I was guessing that https://www.php.net/manual/de/function.unpack.php would be my friend but I just don't get it. Any help would be much appreciated, thanks!
They say that the input is a hex string like '1C000000010028'.
$code = '1C000000010028';
To use unpack() the data must be a string with binaryData. You can convert it with hex2bin.
$binaryData = hex2bin($code);
// "\x1c\x00\x00\x00\x01\x00\x28"
Now you could use unpack.
$arr = unpack('Cbyte_0/vUInt16_0/Cbyte_1/vUInt16_1/Cbyte_2',$binaryData);
/*
$arr = array (
'byte_0' => 28,
'UInt16_0' => 0,
'byte_1' => 0,
'UInt16_1' => 1,
'byte_2' => 40,
)
*/
Individual data types such as Boolean and UInt4 are not included in the pack/unpack formats. To get this data you have to work with the bit operators.
Just one example of this:
$byte_0bit2 = (bool)($arr['byte_0'] & 0b00000100);
This can lead to further questions, the answers of which can be found here on Stackoverflow.
I get through Modbus some 4-Byte Float Values.
I get this 4 bytes in an array:
Array ( [0] => 67 [1] => 105 [2] => 25 [3] => 154 )
After some Bitconversion I made this:
1000011011010010001100110011010
when putting this binary string into a online converter such as
https://www.binaryconvert.com/result_float.html?hexadecimal=4369199A
I get the value of 2.331E2 which is correct (233.1).
However I fail to convert this binary in a PHP float variable. I tried to point the address to a float variable, but did not succeed.
How can I convert this binary string or the array above into a php float?
Added:
The pointer Idea was stupid, since php does not let me define the type of variable. So I tried a different approach using unpack to a float type. But it does not work either:
// This represents a 4 byte float read from modbus
$array=array(67,105,25,154);
$array=array_reverse($array);
print_r($array);
for ($i=0;$i<count($array);$i++) {
$t+=pow(2,$i*8)*$array[$i];
}
echo '<br>Binary: '.decbin($t). ' - This would be the correct Binary for 233.1';
echo '<br>float: ';
print_r(unpack('f',$t));
This code results in:
Array ( [0] => 154 [1] => 25 [2] => 105 [3] => 67 )
Binary: 1000011011010010001100110011010 - This would be the correct Binary for 233.1
float: Array ( [1] => 6.5189725839687E-10 )
No chance to get my 233.1 :(
I know I come with a possible answer a little bit later but maybe others found useful.
The conversion is a little bit complicated, I worked few hours on it to include in my application.
Firstly I created a function to get value of the Mantissa, then calculated a float number. I didn't created function for the calculation of the exponent and sign.
This example is valid for positive float numbers, for more details read this:
HOW REAL (FLOATING POINT) AND 32-BIT DATA IS ENCODED IN MODBUS RTU MESSAGES
And the script:
$array=array(67,105,25,154);
$result = pow(2,(((($array[0] * 256 + $array[1]) & 32640) >> 7)-127)) * calcMantissa((($array[1] & 127) << 16) + ($array[2] << 8) + $array[3]+1);
echo $result . "\n";
function calcMantissa($nb) {
$retValue = 1;
for ($i = 0; $i < 22; $i++) {
$retValue = $retValue + (($nb & (1 << (22 - $i))) > 0) / (pow(2,($i+1))) ;
}
return $retValue;
}
which gave the following result:
233.10000610352
I'm writing a PHP website that is accessing an encrypted MySQL database. The database is currently a back end to a VB.Net Windows forms program. This is all working fine, but I want to the PHP website to access some of the data and be able to decrypt/encrypt it. The fields are encrypted using Blowfish code originally written by David Ireland in VB6 and converted by Todd Acheson with a few tweaks from myself.
With the PHP Blowfish examples I've seen, the $iv is set at random, but I need it to be set to the same as that created in VB, so I'm attempting to convert the VB code to PHP.
I've started converting the code line by line, and from a technical perspective, it seems OK, but testing the first part of it doesn't provide the same results as with VB
Setting the key:
Dim aKey() as Byte = cv_BytesFromHex(MySecretKey)
Public Function cv_BytesFromHex(ByVal sInputHex As String) As Object
' Returns array of bytes from hex string in big-endian order
' E.g. sHex="FEDC80" will return array {&HFE, &HDC, &H80}
Dim i As Long
Dim M As Long
Dim aBytes() As Byte
If Len(sInputHex) Mod 2 <> 0 Then
sInputHex = "0" & sInputHex
End If
M = Len(sInputHex) \ 2
ReDim aBytes(M - 1)
For i = 0 To M - 1
Dim x = "&H" & Mid(sInputHex, i * 2 + 1, 2)
Debug.Print(x + " " + Val(x).ToString)
aBytes(i) = Val(x)
Next
cv_BytesFromHex = aBytes 'CopyArray(aBytes)
Return cv_BytesFromHex
End Function
Converting this function to PHP5.
public function cv_BytesFromHex($inputstring)
{
// Returns array of bytes from hex string in big-endian order
// e.g. shex="fedc80" will return array {&hfe, &hdc, &h80}
$i=0;
$m=0;
if (strlen($inputstring)/2 <> (int)(strlen($inputstring)/2)) {
$inputstring = "0".$inputstring;
}
$m = strlen($inputstring)/2;
echo 'Length '.strlen($inputstring).' = '.$m." elements</br>";
$abytes=array_fill(0,$m-1,0) ;
for ($i=0; $i<=$m-1;$i++) {
$raw=substr($inputstring, $i * 2 , 2);
$hexed=hexdec($raw);
echo 'Raw ='.$raw.' = '.$hexed.'</br>';
$abytes[$i]=$hexed;
}
return $abytes;
}
Testing with the key "1check".
VB output:
&H1C 28
&Hhe 0
&Hck 12
PHP output:
Length 6 = 3 elements
Raw =1c = 28
Raw =he = 14
Raw =ck = 12
So.. in this example, "1C" and "ck" give me the same values, but "he" doesn't
another example:
key =10stack
vb
&H01 1
&H0s 0
&Hta 0
&Hck 12
php
Length 8 = 4 elements
Raw =01 = 1
Raw =0s = 0
Raw =ta = 10
Raw =ck = 12
This one works:
key =1234wxyz
vb
&H12 18
&H34 52
&Hwx 0
&Hyz 0
php
Raw =12 = 18
Raw =34 = 52
Raw =wx = 0
Raw =yz = 0
Does anyone know why?
so, there is no errors here. h is ignored by hexdec and only e is decoded. cause...
https://en.wikipedia.org/wiki/Hexadecimal there is no h :)
and in VBA Val function returns 0, cause he is not valid hex-combination
<?php
function myHex($str)
{
if ($str === dechex(hexdec($str))) {
return hexdec($str);
}
return 0;
}
var_dump(myHex("he")); // returns 0
I am being sent encrypted test data from a U2 system to see if it can be handled and utilised to increase security.
The SUBROUTINE generating the encrypted test data in U2 is:
RESULT=''
ALGORITHM="rc2-cbc" ; * 128 bit rc2 algorithm in CBC mode
MYKEY="23232323" ; * HEX - Actual Key
IV= "12121212" ; * HEX - Initialization Vector
DATALOC=1 ; * Data in String
KEYLOC=1 ; * Key in String
ACTION=5 ; * Base64 encode after encryption
KEYACTION=1 ; * KEY_ACTUAL_OPENSSL
SALT='' ; * SALT not used
RESULTLOC=1 ; * Result in String RESULT
OPSTRING = ''
RETURN.CODE=ENCRYPT(ALGORITHM,ACTION,DATASTRING,DATALOC,MYKEY,KEYLOC,KEYACTION,SALT,IV,OPSTRING,RESULTLOC)
RETURN.CODE = OPSTRING
The data being generated and encrypted is:
[RAWDATA] => Array
(
[196346] => 05FOAA
[196347] => 05KI
[196328] => 99FOZZ16S10
)
[ENCRYPTED] => Array
(
[196346] => e0XB/jyE9ZM=
[196347] => iaYoHzxYlmM=
[196328] => BS/YmNtlzI95c9NLpl4JVHLJwI/MO3zJm6FKVqu2tcM=
)
I am using the same information in PHP using openssl_decrypt:
$encdata = array_value;
$encryptionMethod = ALGORITHM; //"rc2-cbc"
$encryptionKey = MYKEY;//"23232323"
$options = 0;
$iv = IV; //"12121212"
$decryptedMessage = openssl_decrypt( $encdata, $encryptionMethod, $encryptionKey, $options, $iv );
Return value: bool(false)
I have tried different combinations of $options and tried encrypting the same data myself and I get different results.
I have to wait 24 hours to get a new file with any changes so I wanted to cover off as many problems as possible.
I have read over the documentation and I feel that the following could potentially be issues:
ACTION=5 which I can only find 4 potential options from U2 docs - 1 - Encrypt, 2 - Encrypt, the Base64 encode, 3 - Decrypt, 4 - Base64 decode, then decrypt - Is it as simple as this being wrong? I hope so but want to cover of any other possible problems
$encdata - I have tried with OPENSSL_RAW_DATA and 0 which I can't tell because the ACTION=5 which is neither Encrypt OR Encrypt & base64 encode
$encryptionMethod - I don't think rc2-cbc is a valid option in PHP on my server but can't say categorically - I have suggested to change this to AES256
$encryptionKey - is this ok to be a string of 8 chars? Does it need to be a specific length and does it need to be in binary? (Docs have conflicting info)
$iv - same as above - is 8 chars and non-binary ok?
Any other insights before I send this off for overnight updates would be greatly appreciated.
PHP Fiddle with testing: http://phpfiddle.org/main/code/ixax-umq3
I am using the trader library of PHP.
I use the trader_bbands() function
$bBand = trader_bbands( $NumberArray,
25,
TRADER_REAL_MIN,
TRADER_REAL_MIN,
TRADER_MA_TYPE_EMA
);
It returns three arrays.
$bBand[0]; // upper-edge of the Bollinger Band ( an upline )
$bBand[1]; // central line the Bollinger Bands surround ( a moving average )
$bBand[2]; // lower-edge of the Bollinger Band ( a downline )
My original $NumberArray values are all around 2000.0
$bBand[1] is simple moving average so, it returns the numbers around 2000.
However $bBand[0] and $bBand[2] return values
like this below (example cited from var_dump() )
double(3.1325286910105E+38)
[105] =>
double(3.1907365920756E+38)
[106] =>
double(3.1907365920756E+38)
[107] =>
double(3.1740850650235E+38)
[108] =>
double(3.1498571396175E+38)
Q1: What does this array mean?
What I expect from Bollinger Band is array around 2000 + α, or 2000 - α though.
A1:1. Review the php-library documentation on trader_bbands(), as a first step.2. Publish MCVE-altogether-with-a-DataSET to allow validation against a common DataSET3. Compare reference implementations to prove { PASS | FAIL }-status of Trader php-library implementation.
Ad Step 1.:array trader_bbands ( array $real [, integer $timePeriod [, float $nbDevUp [, float $nbDevDn [, integer $mAType ]]]] )
Let's agree to set $nbDevUp = 1.0, not a technically smallest float TRADER_REAL_MINLet's agree to set $nbDevDn = 1.0.
Let's agree to set $timePeriod = 7
Let's agree to set $real
$real = array(
0 => 2000.0,
1 => 2001.0,
2 => 2002.0,
3 => 2003.0,
4 => 2004.0,
5 => 2005.0,
6 => 2006.0,
);
Expectations:
The .std()-sigma-related values ought get into a fair fashion, independently of not knowing all implementation details about the Trader php-library model of trader_bbands() calculus, particularly in the TRADER_MA_TYPE_EMA mode, missing the exponential-weighting details used inside their model.
Nevertheless
A) There ought be sure all differencesbetween $bBand[0][i] - $bBand[1][i] == $bBand[1][i] - $bBand[2][i] to be == 2.0
B) There ought be a value of what value of the exponent was used in .ewma()-method documented somewhere in Trader php-library.
Well, sure, without such value, one may resort to a brute-force reverse search for a matching value used, but it may be a rather inefficient method to prove the $bBand[1] values are calculated in Trader php-library in a manner compatible to the common Quant-practice to use ewmaEXP = 2.0 / ( timePeriod + 1 ).