Equivalent PHP GZIP Compression like in VB.NET - php

I'm migrating a web service that was developed in VB.NET to PHP
I explain:
In VB. NET I have a method that compresses a single string with GZIP. ("Hello world!")
The method in the web service returns an array of bytes.
Then the array of bytes is received on a device with android, decompressed and converted to a string, this process works perfect.
the method in VB.NET, is this:
<WebMethod(Description:="GZIP Test")> _
Public Function GZIP() As Byte()
Dim vTest As String = "Hello world!"
Dim vBuffer1() As Byte = StrToByteArray(vTest)
Dim vBuffer2() As Byte = Compress(vBuffer1)
Return vBuffer2
End Function
Private Function StrToByteArray(ByVal str As String) As Byte()
Dim encoding As New System.Text.UTF8Encoding()
Return encoding.GetBytes(str)
End Function
Private Function Compress(ByVal Bits() As Byte) As Byte()
On Error Resume Next
Using ms As New MemoryStream(), zipMem As New GZipStream(ms, CompressionMode.Compress, True)
zipMem.Write(Bits, 0, Bits.Length)
zipMem.Close()
Return ms.ToArray
End Using
End Function
this method returns me the following value:
<base64Binary>H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ir6dl2WVXlV1Oftd/x+VGYUbDAAAAA==</base64Binary>
I want PHP return me the SAME VALUE.
the tests I've done in PHP returns me the following.
function GZIP() {
ob_start ( 'ob_gzhandler' );
return base64_encode(gzdeflate('Hello world!', 9));
}
the value returned in PHP is:
80jNyclXKM8vyklRBAA=
Why ? There is an example that returns the same ?
Thanks in advance for all.

You are using the wrong de-/compression algorithm. Use phps gzcompress() and gzuncompress() instead.

First off, you can't require the exact same result. All you can require of a lossless compressor is that it reproduce exactly the same input when decompressed.
Second, you want to use gzencode to produce gzip streams. Neither gzdeflate nor gzcompress will do that. The former produces raw deflate streams, and the second zlib streams. (Don't get me started about the misleading names and the messed up PHP documentation about them.)

Related

Openssl_decrypt returns empty output

Hello everyone i was trying to decrypt some encrypted strings i encrypted with python .
the problem is that sometimes it decrypts correctly and sometimes it gives empty output for no obvious reason and i couldn't find any solution for it.
here's the code i'm using to decrypt on PHP .
knowing that online AES decryption tools decrypts it correctly.
$rtk=base64_decode('zgdHfETipvp1E5m3ix5NFOLuX8N0+zAIBzg+GOq0cTQ=');
$method = "aes-128-ecb";
$key = 'aaaaaaaaaaaaaaaa';
$email=openssl_decrypt($rtk, $method, $key,OPENSSL_RAW_DATA);
i would apreciate your help !
EDIT :
The python code i used to encript the string :
import pandas as pd
from Crypto.Cipher import AES
import names
import urllib.parse
import base64
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad
email="zqeafzeqaf23#example1.com"
key = b'aaaaaaaaaaaaaaaa'
data = email.encode('ascii', 'ignore')
cipher = AES.new(key, AES.MODE_ECB)
b64string = base64.urlsafe_b64encode(cipher.encrypt(pad(data,16)))
print(b64string)
Your Python code uses urlsafe_b64encode, but your PHP code uses the normal base64 variant (in fact your example data in the PHP code contains a + character so couldn’t have been produced by that Python code).
This could explain why the decryption is failing. If the url safe base 64 output from Python contains a - or _ character, PHP will simply strip that character from the string before decoding the rest of it. This will leave a string that is not a multiple of the AES block length and the decryption will fail.
You should ensure you are using the same base 64 variant to encode and decode. It doesn’t look like PHP provides a URL safe variant, you might need to use something like strtr before decoding to convert the base 64 into a normal variant:
$data = strtr($data, '-_', '+/');
$decoded = base64_decode($data);

how to pass a large string from a delphi dll to a php extension

I have written a php extension in Visual Studio Express for PHP 7.2 NTS for Windows 7 (all 64-bit). I am using it to access a 3rd party .dll written in C++ and it is working fine.
Now I want it to access a .dll that I am writing in Delphi XE6. The function in the .dll returns a string as a PAnsiChar. It is actually a base64 encoded jpeg image, so can be quite large. I chose to send it as base64 encoded string because I can't see any way of passing an image or array of bytes from the extension back to PHP.
My Delphi code is:
function dem_get_map_img(imgdata: PAnsiChar): int32; stdcall;
var
base64str: ansistring;
begin
base64str := 'test return value'; // the actual image data will go here
imgdata := PAnsiChar(base64str);
Result := 27; // some meaningful value will be used later
end;
My PHP extension code is:
PHP_FUNCTION(dem_get_map_img)
{
hGetProcIDDelphiDLL = LoadLibrary(_T("delphiDLL.dll"));
if (!hGetProcIDDelphiDLL) RETURN_STRING("dll not loaded");
int rc;
char imgdata[AS_MAXCH];
if (ZEND_NUM_ARGS() != 0) RETURN_STRING("wrong param count loaded");
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_get_map_img");
if (!lpfnGetProcessID) RETURN_STRING("function not found");
typedef int32(__stdcall * pICFUNC)(char *imgdata);
pICFUNC dem_get_map_img;
dem_get_map_img = pICFUNC(lpfnGetProcessID);
rc = dem_get_map_img(imgdata);
FreeLibrary(hGetProcIDDelphiDLL);
array_init(return_value);
add_assoc_long(return_value, "retflag", rc);
add_assoc_string(return_value, "imgdata", imgdata);
}
My PHP code is:
$outval = dem_get_map_img();
var_dump($outval);
which gives me:
array(2) {
["retflag"]=>
int(27)
["imgdata"]=>
string(4) "�$�"
}
Not what I was hoping for.
Firstly, I have noticed that AS_MAXCH will apparently only allow me 255 characters, which is going to be a problem (help?) but shouldn't be the problem so far.
I have read various similar questions and assume that deallocated memory may be the problem, but so far I have been unable to figure out what to do about it.
I have seen people recommend using CoTaskMemAlloc, but how do I do that in Delphi?
What I really need to do is pass a Jpeg image from my Delphi dll to the PHP extension and into my PHP code, so if there is a better way to do that then I am open to suggestions. My knowledge of C/C++ and PHP extensions is quite limited (you already knew that didn't you).
Any help would be appreciated.
UPDATE:
How stupid can you get (.. can I get)?
I just realised what I was doing wrong in the Delphi function.
Revised Delphi function:
function dem_get_map_img(imgdata: PAnsiChar): int32; stdcall;
var
base64str: ansistring;
begin
base64str:= 'test return value';
StrPCopy(imgdata, base64str);
Result := 27;
end;
Fill the PAnsiChar, don't create a new one!
I am still curious if anyone has a better suggestion for passing an image or large block of data to PHP though.
UPDATE 2:
Well, with many thanks to David Heffernan for pointing me in the right direction, I think I have it.
I split the Delphi function so that I now have one function that prepares the string and returns the size,
Result := length(MapImage) * sizeof(ansichar) + 1;
and another one that returns the actual string data as before.
So now I call the first function to prepare the data and use the returned data size to allocate the memory before calling the second function.
My new extension code is:
PHP_FUNCTION(dem_get_map_img)
{
hGetProcIDDelphiDLL = LoadLibrary(_T("delphiDLL.dll"));
if (!hGetProcIDDelphiDLL) RETURN_STRING("not loaded");
long rc, imgsize;
char * imgdata;
if (ZEND_NUM_ARGS() != 0) RETURN_STRING("wrong param count loaded");
FARPROC lpfnGetPrepID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_prepare_map_img");
if (!lpfnGetPrepID) RETURN_STRING("prepare function not found");
typedef int32(__stdcall * pICprep)(long wid, long hei);
pICprep dem_prepare_map_img;
dem_prepare_map_img = pICprep(lpfnGetPrepID);
imgsize = dem_prepare_map_img(900, 450);
imgdata = (char*)malloc(imgsize);
FARPROC lpfnGetGetID = GetProcAddress(HMODULE(hGetProcIDDelphiDLL), "dem_get_map_img");
if (!lpfnGetGetID) RETURN_STRING("get function not found");
typedef int32(__stdcall * pICget)(char *imgdata);
pICget dem_get_map_img;
dem_get_map_img = pICget(lpfnGetGetID);
rc = dem_get_map_img(imgdata);
FreeLibrary(hGetProcIDDelphiDLL);
array_init(return_value);
add_assoc_long(return_value, "retflag", rc);
add_assoc_long(return_value, "imgsize", imgsize);
add_assoc_string(return_value, "imgdata", imgdata);
free(imgdata);
}
And I have a nice map on my web page!
My only real concern now is that free(imgdata) is being reached. As I understand it the extension function only returns return_value at the end of the function, not immediately as with RETURN_STRING().

CryptoPP vs PHP Base64 Encoding/Decoding

I am trying to create a communication exchange between an application in PHP and C++ (CryptoPP).
I have the following code in PHP:
$in = "ALApfWG920ZFle/2r6CkXKXt+zG5tiw7Gw9ZLl1mKRNP9fyb12T92e9rTQF4JeapXSrZVBPyrGx52l4zmu+wr3u2EQW7CeYFbl9h8y5+xx0MPOL/1nyX6ENzo755klTy5AxcM9GMrpKt689i79ouuxceA2bCa0cpWMUv4c2dHN8nKaXDSyCW04dRglFds9CVb29JgQamFRc7H8yjPPdk/FIMDt3xCDOKjoT5VGM1v1Tsyo92qCSFW9N4xXqLr5NUO0hv5u+kVCg0P/gWbgSSNsflXjyqV+dBp3YzKdxHGQXbpl8IQvec95GjL60zQ7IS/rWOZg40+IrwbhvoWHUQIkM="
$out = base64_decode($decode)
It decodes the text and returns a binary string, as expected.
I am doing a similar command using CryptoPP in C++:
string out;
string in = "ALApfWG920ZFle/2r6CkXKXt+zG5tiw7Gw9ZLl1mKRNP9fyb12T92e9rTQF4JeapXSrZVBPyrGx52l4zmu+wr3u2EQW7CeYFbl9h8y5+xx0MPOL/1nyX6ENzo755klTy5AxcM9GMrpKt689i79ouuxceA2bCa0cpWMUv4c2dHN8nKaXDSyCW04dRglFds9CVb29JgQamFRc7H8yjPPdk/FIMDt3xCDOKjoT5VGM1v1Tsyo92qCSFW9N4xXqLr5NUO0hv5u+kVCg0P/gWbgSSNsflXjyqV+dBp3YzKdxHGQXbpl8IQvec95GjL60zQ7IS/rWOZg40+IrwbhvoWHUQIkM=";
CryptoPP::StringSource decryptor(in, true,
new CryptoPP::Base64Decoder(
new CryptoPP::StringSink(out)
));
However, when I inspect the out string, it is empty.
Could someone please pin-point what I am doing wrong?
You cannot see the binary data because they start with a zero (\0).
\0 terminates a string, so you cannot see anything, but your data is stored.
Check:
out.size()
You can access your data with:
const char* data = out.c_str();
char* firstByte = data[0];

PHP and MATLAB base64_decode works differently

I am trying to write a base64 decode function in MATLAB.
In PHP, if I call built-in base64 decode function
$decodedStr = base64_decode($encodedStr)
$decodedStr is the result I want.
Now, I need to pass $encodedStr from PHP to MATLAB (as a parameter), and in MATLAB, I decode the string, same as PHP code above.
function base64_decode_matlab(x)
%x is same value as $encodedStr
base64 = org.apache.commons.codec.binary.Base64;
decodedStr1 = base64.decode(uint8(x));
end
However, it seems like the result is different than the result from PHP. What's wrong with my MATLAB code and how can I make the MATLAB base64 decode function works same as the PHP base64_decode function?

Mime / Base 64 encoding

I need a way to encode a string to Mime/Base64 in Delphi 7 and PHP
These two encoders must be compatible :)
The Indy-Project provides base64 encoder/decoder classes. You can find the documentation here.
For PHP, you can use the PHP-internal functions base64_encode and base64_decode.
The unit EncdDecd has been included since Delphi 6; below are the Mime compatible base64 functions it contains.
This cached post from FlexVN (the original post is not always on-line) explains how to do the base64 thing between PHP and Delphi using the EncdDecd unit.
unit EncdDecd;
interface
uses Classes, SysUtils;
procedure EncodeStream(Input, Output: TStream);
procedure DecodeStream(Input, Output: TStream);
function EncodeString(const Input: string): string;
function DecodeString(const Input: string): string;
function DecodeBase64(const Input: AnsiString): TBytes;
function EncodeBase64(const Input: Pointer; Size: Integer): AnsiString;

Categories