Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:68770 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 27037 invoked from network); 30 Aug 2013 23:50:30 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Aug 2013 23:50:30 -0000 Authentication-Results: pb1.pair.com header.from=tjerk.meesters@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=tjerk.meesters@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.160.51 as permitted sender) X-PHP-List-Original-Sender: tjerk.meesters@gmail.com X-Host-Fingerprint: 209.85.160.51 mail-pb0-f51.google.com Received: from [209.85.160.51] ([209.85.160.51:48208] helo=mail-pb0-f51.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8F/35-00443-4CF21225 for ; Fri, 30 Aug 2013 19:50:28 -0400 Received: by mail-pb0-f51.google.com with SMTP id jt11so2441947pbb.38 for ; Fri, 30 Aug 2013 16:50:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=references:mime-version:in-reply-to:content-type :content-transfer-encoding:message-id:cc:from:subject:date:to; bh=FDOra+CvBgTTQYyd898e58HNwxT3MSO3dH2NFwtFJv4=; b=chg2DCJ6hSZH9txtNYqR7w8WvyY9HO6JFtW2N0+iecp6ibCnOx88STCdn6qRuxT04E XKDGhQh1JGyuyLyzhlQ6yGYspqbERyJHzw4TD+0wnMNS/jUXghD8hRzvD/nqOUsLhpTE KX4i2S93/OinM4n0YQS2NDhpO1yn6OmAmNKNMe/RAN29nbnCWI9+WMVweLsG0sJZx0qe gqoCGvDbxSVfN6LTlMr/4M45PlX8iCvgiEou7076cxUY2Ty0BvUmK1lHeZdD/+Uv1Gd7 Crhd6Z2CrcN4DGZBjGz2iPhuV3uluEZ0GQ2NuWejiXQo9VSKuu4GWf1QwtoeXpgnGlMb 3oUA== X-Received: by 10.68.237.3 with SMTP id uy3mr12688932pbc.155.1377906625348; Fri, 30 Aug 2013 16:50:25 -0700 (PDT) Received: from [192.168.1.105] (bb42-60-19-235.singnet.com.sg. [42.60.19.235]) by mx.google.com with ESMTPSA id xs1sm682627pac.7.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 30 Aug 2013 16:50:24 -0700 (PDT) References: Mime-Version: 1.0 (1.0) In-Reply-To: Content-Type: multipart/alternative; boundary=Apple-Mail-28914EC3-1C4E-42B7-9311-2D99502853D1 Content-Transfer-Encoding: 7bit Message-ID: <4AA16472-E903-463B-9B36-C8ABE08C86EF@gmail.com> Cc: PHP internals X-Mailer: iPhone Mail (10B329) Date: Sat, 31 Aug 2013 07:50:20 +0800 To: Rasmus Schultz Subject: Re: [PHP-DEV] Re: crc32() and ip2long() return values From: tjerk.meesters@gmail.com (Tjerk Meesters) --Apple-Mail-28914EC3-1C4E-42B7-9311-2D99502853D1 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Hi, On 30 Aug, 2013, at 11:29 PM, Rasmus Schultz wrote: > No replies probably means no one cares. oh well. >=20 > For the record, the examples I posted are wrong - the correct way to > convert the long values consistently appears to be: >=20 > list($v) =3D array_values(unpack('l', pack('l', ip2long('255.255.255.0')))= ); I recognise this from a comment on one of my SO answers here: http://stackov= erflow.com/questions/13419921/how-should-a-crc32-be-stored-in-mysql/13420281= #13420281 Instead of using list() and array_values() you can use current() on the retu= rn value to get the first array element from unpack()'s result.=20 echo current(unpack('l', pack('l', crc32(...)))); Admittedly only makes it marginally nicer to look at :) >=20 > I missed the fact that array_values() returns an array, and for some reaso= n > the return-value from unpack() is base-1 with apparently no way to change > the key to a 0. >=20 > As an aside, the information I posted on the manual pages in the comments > is wrong, and the site currently offers no way to edit or remove a > comment... dangit... >=20 >=20 >=20 > On Tue, Aug 27, 2013 at 12:05 PM, Rasmus Schultz wrot= e: >=20 >> Dear list, >>=20 >> I recently ran into big problems with crc32() and ip2long() both of which= >> I was using in the same codebase. >>=20 >> I know these issues have been debated at length in the past, but this >> really needs to be fixed. >>=20 >> Anytime you persist these values (to any external medium, files or >> databases) you're sitting on a time bomb. >>=20 >> I realize some of you have countless technical arguments why these >> functions "work as they're supposed to", but php is a high-level language= , >> and these functions do not work consistently across platforms. >>=20 >> It can't be the developer's responsibility to write unit-tests for >> return-values on internal functions - nor should we need to write elabora= te >> wrapper-functions for these functions to get them to work consistently. >>=20 >> There are dozens (if not nearing 100) different user-land solutions to >> this problem, so it's not like the need isn't there - anyone who has ever= >> used these functions probably needed a work-around. The need for an >> enormous red WARNING label, and elaborate explanation on the crc32() >> documentation page says it all - nothing this simple, that has been >> standardized for this long, should require an elaborate explanation, >> complicated work-arounds or for that matter a lot of thought on the >> developer's side. >>=20 >> Since a signed 32-bit integer value is the lowest common denominator, >> that's what the functions ought to return, so that at least the return >> value is consistent across platforms, and you can decide (for example) >> whether to persist it to a signed or unsigned INT in a database, and exce= pt >> it to work the same everywhere. (Databases at large, and at least MySQL, >> correctly persists either signer or unsigned INT values across platforms.= ) >>=20 >> The simplest work-around I have been able to come up with so far, is this= : >>=20 >> var_dump(unpack('l', pack('l', ip2long('255.255.255.0')))); >>=20 >> var_dump(unpack('l', pack('l', crc32('123456789_00_0')))); >>=20 >> Forcing the value into smaller (on some platforms) 32-bit integer, and >> then unpacking it, provides a consistent value on 32-bit and 64-bit >> systems, and on Windows. >>=20 >> Of course there is backwards compatibility to consider for this broken >> behavior, so I propose the simplest solutions is to just add a new pair o= f >> replacement functions. You don't need to deprecate the existing functions= , >> because they work as prescribed, however useless they may be for any >> practical applications. >>=20 >> The new functions and backwards compatible implementations for older >> versions of php might look like this: >>=20 >> /** >> * @param string >> * @return int a signed (32-bit) integer value >> */ >> function ip2int($ip_string) { >> return unpack('l', pack('l', ip2long($ip_string))); >> } >>=20 >> /** >> * @param int a signed integer value >> * @return string >> */ >> function int2ip($ip_int) { >> return long2ip($ip_int); >> } >>=20 >> /** >> * @param string >> * @return int a signed integer value >> */ >> function crc32i($string) { >> return unpack('l', pack('l', crc32($string))); >> } >>=20 >> int2ip() would just be an alias for long2ip(). >>=20 >> I spent almost a full day fighting with these functions and testing >> work-arounds, and I bet every php developer who encounters a need for one= >> of these functions will some day sooner or later go through the same. >>=20 >> Userland solutions are not solutions to fundamental problems that affect >> everyone who uses the functions. >>=20 >> Arguing that this behavior is "correct" by some technical definition, is >> futile - the behavior is problematic for practical reasons, so technical >> circumstances don't really matter here. Core functions need to actually >> work consistently and predictably for as many users as possible - >> optimizing for C developers and people with deep technical knowledge of >> operating system and compiler specifics does not make sense for a languag= e >> like php. >>=20 >> Please look for reasons to agree rather than disagree out of spite. >>=20 >> As said, I know this has been debated at length in the past, and always >> with the same outcome - but the simple fact is that these functions don't= >> work for the end-users, and they do not provide proper cross-platform >> support. >>=20 >> No one cares how integers work internally, in C, in the CPU, or in the VM= , >> and it's not relevant. >>=20 >> There is no need to put anyone through all this unnecessary hardship. >>=20 >> These functions need to work **for php developers**. >>=20 >> - Rasmus Schultz >>=20 >>=20 --Apple-Mail-28914EC3-1C4E-42B7-9311-2D99502853D1--