Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:68728 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 42797 invoked from network); 30 Aug 2013 15:29:29 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Aug 2013 15:29:29 -0000 Authentication-Results: pb1.pair.com smtp.mail=rasmus@mindplay.dk; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=rasmus@mindplay.dk; sender-id=unknown Received-SPF: error (pb1.pair.com: domain mindplay.dk from 209.85.220.174 cause and error) X-PHP-List-Original-Sender: rasmus@mindplay.dk X-Host-Fingerprint: 209.85.220.174 mail-vc0-f174.google.com Received: from [209.85.220.174] ([209.85.220.174:64701] helo=mail-vc0-f174.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C1/02-32511-05AB0225 for ; Fri, 30 Aug 2013 11:29:25 -0400 Received: by mail-vc0-f174.google.com with SMTP id gd11so1390383vcb.5 for ; Fri, 30 Aug 2013 08:29:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type; bh=UH1ov3EEzsjWTy6N+Ps1OaPnntFNhee4vW9u28G6G6c=; b=SQeNsik/5ZzzNyNS7YUnY/OIpAlB3Tq+Rv9AfS/6GEbN2u7+OPOk0ONffJSNoU0R0H gRT3fHcrFe5ISovQFaH+S0U1HI+ANe6I7/wCT/YDlXbaCpH0knUMrRlhU2tQ0seukKQg sx7f16IOsOT7gmyQWHdS8xUVehZZcXzg4Fpy2DuY0lfIDT5vzUvLAORY4kpdnl/9G2fR Bqb68qcyr78e/jSOgthe78n/v0VxfutJe5z2C5FL5hu28fn2QX3VuVkqT1qolFQZCzay jpNti+c36SWIV0A28/QdvXGFPopskmgAouo5ohvpqWvHVPqd3In5JtUZ6FGJIiZk8GPX shhg== X-Gm-Message-State: ALoCoQkPWrg/Gl3CECcN9zw+/6gU3M8mGJmLabEeTnTnvMb3CjC/NuL0jNXhoP0d5effJHAtlrcV MIME-Version: 1.0 X-Received: by 10.58.201.227 with SMTP id kd3mr9011425vec.14.1377876553625; Fri, 30 Aug 2013 08:29:13 -0700 (PDT) Received: by 10.58.190.194 with HTTP; Fri, 30 Aug 2013 08:29:13 -0700 (PDT) In-Reply-To: References: Date: Fri, 30 Aug 2013 11:29:13 -0400 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary=047d7bd7579c86064a04e52be28f Subject: Re: crc32() and ip2long() return values From: rasmus@mindplay.dk (Rasmus Schultz) --047d7bd7579c86064a04e52be28f Content-Type: text/plain; charset=ISO-8859-1 No replies probably means no one cares. oh well. For the record, the examples I posted are wrong - the correct way to convert the long values consistently appears to be: list($v) = array_values(unpack('l', pack('l', ip2long('255.255.255.0')))); I missed the fact that array_values() returns an array, and for some reason the return-value from unpack() is base-1 with apparently no way to change the key to a 0. 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... On Tue, Aug 27, 2013 at 12:05 PM, Rasmus Schultz wrote: > Dear list, > > I recently ran into big problems with crc32() and ip2long() both of which > I was using in the same codebase. > > I know these issues have been debated at length in the past, but this > really needs to be fixed. > > Anytime you persist these values (to any external medium, files or > databases) you're sitting on a time bomb. > > 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. > > It can't be the developer's responsibility to write unit-tests for > return-values on internal functions - nor should we need to write elaborate > wrapper-functions for these functions to get them to work consistently. > > 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. > > 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 except > it to work the same everywhere. (Databases at large, and at least MySQL, > correctly persists either signer or unsigned INT values across platforms.) > > The simplest work-around I have been able to come up with so far, is this: > > var_dump(unpack('l', pack('l', ip2long('255.255.255.0')))); > > var_dump(unpack('l', pack('l', crc32('123456789_00_0')))); > > 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. > > 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 of > 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. > > The new functions and backwards compatible implementations for older > versions of php might look like this: > > /** > * @param string > * @return int a signed (32-bit) integer value > */ > function ip2int($ip_string) { > return unpack('l', pack('l', ip2long($ip_string))); > } > > /** > * @param int a signed integer value > * @return string > */ > function int2ip($ip_int) { > return long2ip($ip_int); > } > > /** > * @param string > * @return int a signed integer value > */ > function crc32i($string) { > return unpack('l', pack('l', crc32($string))); > } > > int2ip() would just be an alias for long2ip(). > > 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. > > Userland solutions are not solutions to fundamental problems that affect > everyone who uses the functions. > > 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 language > like php. > > Please look for reasons to agree rather than disagree out of spite. > > 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. > > No one cares how integers work internally, in C, in the CPU, or in the VM, > and it's not relevant. > > There is no need to put anyone through all this unnecessary hardship. > > These functions need to work **for php developers**. > > - Rasmus Schultz > > --047d7bd7579c86064a04e52be28f--