I am sending strings from my objective-c app to a PHP script over HTTP. I need to websafe these strings.
I am currently encoding with Google Toolbox for Mac GTMStringEncoding rfc4648Base64WebsafeStringEncoding and decoding with base64_decode() on the PHP end. Works great 99% of the time.
Unfortunately, this encoding is not entirely websafe as it includes some web-interpreted characters ("/" and "-"). The regular GTMStringEncoding rfc4648Base64StringEncoding also includes web-interpreted characters.
Is uuencoding the data the way to go? I see that PHP already has uudecode support, will I have top roll my own on the objective-c side?
If not uuencode, then what?
OK, it seems that PHP did not default support Section 5 of RFC 4648, "Base 64 Encoding with URL and Filename Safe Alphabet." This function allows PHP to handle the 4 out-lier chars before base64_decode:
function base64url_decode($base64url) {
$base64 = strtr($base64url, '-_', '+/');
$plainText = base64_decode($base64);
return ($plainText);
}
My thanks to the anonymous "Tom" who posted it on PHP.net 6 years ago.
Related
When using PHP with get_file_contents() to read in a file that has been encrypted, it doesn't change any of the encrypted contents.
When replicating it in NodeJS though through fs.readFile(file, "utf8") or even fs.readFileSync(file, "utf8") the encryption is somehow manipulated as when being checked the same way as the PHP version it fails.
Reading in that same file without encryption works with fs.readFile(file, "utf8").
I have tried ignoring encoding all together, swapping to binary encoding and nothing seems to work.
Is there a way to keep fs.readFile() or fs.readFileSync() from change encryption characters?
You should not use the "utf8" parameter in fs.readFile(file, "utf8").
It seems like the right parameter for you would be "latin1" or its legacy alias "binary" which communicates your intention more clearly.
You can check the available encodings here.
Update: Just to not make you reading through all: PHP starting with
7.1.0alpha2 supports UTF-8 filenames on Windows. (Thanks to Anatol-Belski!)
Following some link chains on stackoverflow I found part of the answer:
https://stackoverflow.com/a/10138133/3716796 by Umberto Salsi
(and on the same question: https://stackoverflow.com/a/2950046/3716796 by Artefacto)
In short: 'PHP communicate[s] with the underlying file system as a "non-Unicode aware program"', and because of that all filenames given to PHP by Windows and vice versa are automatically translated/reencoded by Windows. This causes the errors. And you seemingly can't stop the automatic reencoding.
(And https://stackoverflow.com/a/2888039/3716796 by Artefacto: "PHP does not use the wide WIN32 API calls, so you're limited by the codepage.")
And at https://bugs.php.net/bug.php?id=47096 there is the bug report for PHP.
Though on there nicolas suggests, that a COM-object might work! $fs = new COM('Scripting.FileSystemObject', null,
CP_UTF8);
Maybe I will try that sometimes.
So there is the part of my questionleft : Is there PHP6 out, or was it withdrawn, or is there anything new on PHP about that topic?
// full Question
The most questions about this topic are 1 to 5 years old.
Could php now save a file using
file_put_contents($dir . '/' . $_POST['fileName'], $_POST['content']);
when the $_POST['fileName'] is UTF-8 encoded, for example "Крым.xml" ?
Currently it is saved as
Крым.xml
I checked the fileName variable, so I can be sure it's UTF-8:
echo mb_detect_encoding($_POST['fileName']);
Is there now anything new in PHP that could accomplish it?
At some places I read PHP 6 would be able to do it, but PHP 6 if i I remember right, has been withdrawn. ?
In Windows Explorer I can change the name of a file to "Крым.xml". As far as I have understood the old questions&answers, it should be possible to use file_put_contents if the fileName-var is simply encoded to the encoding used by windows 7 and it's NTFS disc.
There is even 3 old question with answers that claim to have succeeded: PHP File Handling with UTF-8 Special Characters
Convert UTF-16LE to UTF-8 in php
and PHP: How to create unicode filenames
Overall and most approved answers say it is not possible.
I checked all suggested answers already myself, and none works.
How to definitly and with absolute accuracy find out, in which encoding my Win 7 and Explorer saves the filename on my NTFS disc and with German language setting?
As said: I can create a file "Крым.xml" in the Explorer.
My conclusion:
1. Either file_put_contents doesn'T work correctly when handing over the fileName (which I tried with conversions to UTF-16, UTF-16LE, ISO-8859-1 and Windows-1252) to Windows,
2. or file_put_contents just doesn't implement a way to call Windows' own file function in the appropriate way (so this second possibility would mean it's not a bug but just not implemented.) (For example notepad++ has no problems creating, writing and renaming a file called Крым.xml.)
Just one example of the error messages I got, in this case when I used
mb_convert_encoding($theFilename , 'Windows-1252' , 'UTF-8')
"Warning: file_put_contents(dirToSaveIn/????.xml): failed to open stream: No error in C:\aa xampp\htdocs\myinterface.lo\myinterface\phpWriteLocalSearchResponseXML.php on line 26 "
With other conversion I got other error messages, ranging from 'invalid characters' to no string recognized at all.
Greetings
John
PHP starting with 7.1.0alpha2 supports UTF-8 filenames on Windows.
Thanks.
//i've added a new take on this please see Cheating PHP integers . any help will be much appreciated. I've had an idea to trying and hack the storage option of the arrays by packing the integers into unsigned bytes (only need 8 or 16 bits integers to reduce the memory considerably).
Hi
I'm currently working on custom charset detection libraries and created a port from Mozilla's charset detection algorithm and used chardet (the python port) for a helping hand. However, this is extremely memory intensive in PHP (around 30mb of memory if I just load in Western language detection). I've optimised all I can without rewriting it from scratch to load each piece (this would reduce memory but make it a lot slower).
My question is that, do you know of any LGPL PHP libraries that do charset detection?
This would be purely for research to give me a slight guiding hand in the right direction.
I already know of mb_detect_encoding but it's far too limited and brings up far too many false positives with the text files i have (yet python's chardet detects them perfectly)
I created a method which encodes correctly to UTF-8. But it was hard to figure out what is currently encoded so I came to this solution:
<?php
function _convert($content) {
if(!mb_check_encoding($content, 'UTF-8')
OR !($content === mb_convert_encoding(mb_convert_encoding($content, 'UTF-32', 'UTF-8' ), 'UTF-8', 'UTF-32'))) {
$content = mb_convert_encoding($content, 'UTF-8');
if (mb_check_encoding($content, 'UTF-8')) {
// log('Converted to UTF-8');
} else {
// log('Could not converted to UTF-8');
}
}
return $content;
}
?>
As you can see I do a conversion to check if it still the same (UTF-8/16) and if not convert it. Maybe you can use some of this code.
First of all, interesting project you are working on! I'm curious how the end product will be.
Have you take a look at the ICU project already?
I've set up a script that processes incoming emails and creates blog entries on Blogger. I'm using PEAR's Mail_Mime libs (for now) to read the incoming message. The messages often have characters in them that cannot be read by browsers--this happens most often when people use Outlook or cut/paste from MS Word.
So the output at the other end is something like this:
Here is a test post with “quotes” and ‘apostrophes�for what it�s worth, it also has dashes�and other strange formatting cut and paste from MS Word.
You can also see the output in the wild.
It's not hard to fix any specific instance, but each client (hotmail, gmail, outlook, etc) seems to handle things just a bit differently. Mail_Mime only seems to munge the output and, if I turn off Mail_Mime's parsing and try to translate the encoded characters myself using mb_convert_encoding or some manual simulation of this, it's even worse.
Please not that this is not going to be solved by selecting the right encoding type and using decode/encode/convert functions. The incoming formats vary from Windows-1252 to UTF8 to just about anything else mail clients can think of.
Has anyone scripted this before that could save me some time by offering up a sample or advice on the best approach? I've tried all the simple answers and done plenty of experimenting, so please don't bother responding unless you've dealt with a similar issue successfully or have a deep understanding of encoding issues.
The only way to do this is to do it by the spec's which is I'm afraid to pull in the 'Content-Type' mime header, pick up the charset (it'll look like Content-Type: text/plain; charset="us-ascii") then convert to UTF-8, and of course ensure your output on the web is sent as UTF-8 with the right headers.
To solve this problem, and get my message into valid UTF-8 that is readable from a browser, I found this PHP lib, ConvertCharset by Mikolaj Jedrzejak, which worked on almost everything. It still had issues with a specific symbol (=A0) when converting from Windows-1252 or iso-8859-1. So I converted this character manually before setting the code loose.
Here's what it looks like overall:
// decode using Mail_Mime
require 'Mail.php';
require 'Mail/mime.php';
require 'Mail/mimeDecode.php';
$params['include_bodies'] = true;
$params['decode_bodies'] = true; // this decodes it!
$params['decode_headers'] = true;
$decoder = new Mail_mimeDecode($input);
$mime = $decoder->decode($params);
// too much work to put in this example
$charset = ...; //do some magic with $mime->parts to get the character set
$text = ...; //do some magic with $mime->parts to get the text
// fix the =A0 control character; it's already been decoded
// by Mail_Mime, so we need the actual byte code now
// this has to be done before trying to convert to UTF-8
$char = chr(hexdec(substr('A0',1)));
$text = str_replace($char, '', $text);
// convert to UTF-8 using ConvertCharset
require 'ConvertCharset.class.php';
if( strtolower($charset) != 'utf-8' ) {
$converter = new ConvertCharset($charset, 'utf-8', false);
}
$text = $converter->Convert($text);
Then everything is spiffy. It even does the infamous Iñtërnâtiônàlizætiøn conversion, as well as accepting french, spanish, and pastes directly from MS Word :)
I have a string that I would like to encrypt in Python, store it as a cookie, then in a PHP file I'd like to retrieve that cookie, and decrypt it in PHP. How would I go about doing this?
I appreciate the fast responses.
All cookie talk aside, lets just say I want to encrypt a string in Python and then decrypt a string in PHP.
Are there any examples you can point me to?
Use a standard encryption scheme. The implementation is going to be equivalent in either language.
RSA is available (via third party libraries) in both languages, if you need asymmetric key crypto. So is AES, if you need symmetric keys.
There is a good example here:
http://www.codekoala.com/blog/2009/aes-encryption-python-using-pycrypto/
Other links that may help:
http://www.phpclasses.org/browse/package/4238.html
http://www.chilkatsoft.com/p/php_aes.asp
If you're not talking about encryption but encoding to make sure the contents make it through safely regardless of quoting issues, special characters, and line breaks, I think base64 encoding is your best bet. PHP has base64_encode / decode() out of the box, and I'm sure Python has, too.
Note that base64 encoding obviously does nothing to encrypt your data (i.e. to make it unreadable to outsiders), and base64 encoded data grows by 33%.
Well, my first thought would be to use a web server that uses SSL and set the cookie's secure property to true, meaning that it will only be served over SSL connections.
However, I'm aware that this probably isn't what you're looking for.
Although a bit late. Find sample code below using the Fernet library
#Python Code - fernet 1.0 library
from cryptography.fernet import Fernet
key = b"Gm3wFh9OiQHcVc8rcAMm8IOqKOJtk7CbrGRKVhrvXhg="
f = Fernet(key)
token = f.encrypt(b'the quick brown fox jumps over the lazy hare')
print(token)
##gAAAAABiMWVPsStLo42ExcmIqcGvRvCCmnhB5B6dc2JsOm4w-VsE9oJOuk_qYuZvHv5quQR4t_6ZjNJzAdCiDPOtESNzCreJZLwc2X-_apbqKKnBwc3KhmqL-K5X7t1uR1WXuyUEYUtW
<?php
//PHP - kelvinmo/fernet-php v1.0.1 A
require 'vendor/autoload.php';
use Fernet\Fernet;
$key = "Gm3wFh9OiQHcVc8rcAMm8IOqKOJtk7CbrGRKVhrvXhg=" ;
$fernet = new Fernet($key);
$token = "gAAAAABiMWVPsStLo42ExcmIqcGvRvCCmnhB5B6dc2JsOm4w-VsE9oJOuk_qYuZvHv5quQR4t_6ZjNJzAdCiDPOtESNzCreJZLwc2X-_apbqKKnBwc3KhmqL-K5X7t1uR1WXuyUEYUtW";
echo $fernet->decode($token);
?>