Skip to content
This repository has been archived by the owner on Apr 23, 2023. It is now read-only.

Add support for bcmath extension #68

Merged
merged 12 commits into from
Mar 31, 2018
Merged

Conversation

nathanntg
Copy link
Contributor

Thanks for creating this project! I've been using this for a project of mine, and my server does not have the GMP extension. Once I saw that the extension usage was limited to a few pieces of the project, I created a fork that abstracted away the big integer operations allowing use of bcmath as an alternative (and potentially others down the line).

I wanted to offer this back to the project, in case it would benefit others. I totally understand if you want to keep the project simple and avoid introducing the alternative implementations.

The new big integer math is all handled by a BigInteger class that is implementation agnostic. It returns subclasses that use an appropriate engine, determined at run time. Each BigInteger class is immutable and offers an OOP where operations return new instances.

I added tests for the BigInteger class, and it will test both the GMP and bcmath codepaths if the appropriate extensions are present.

In addition, I updated the README and composer file. Unfortunately, I don't think composer has a good way to say require this or this, so I just removed the GMP requirement. (In theory, there could be a pure PHP implementation of BigInteger, but that is probably overkill?)

If this is something you are interested in merging into the project, let me know and I am happy to make further changes.

The implementations are basic, designed only for the narrow needs of the code within the project.
Modify the Base128 and Integer code to rely on the implementation agnositc number class.
Makes it more obvious what can be stored, and move it out of the ASN1 folder as it is not actually part of that implementation, just a behind the scenes detail.
Implement tests for both implemementations, and fix an inconsistency in how modulus is calculated for the bcmath implemementation.
Removed GMP extension from composer requirements. Unofrutnatley, there is not a way to specify alternatives in composer requirements.
@afk11
Copy link
Collaborator

afk11 commented Mar 10, 2018

It looks like you're using tabs instead of spaces.

Its usually best practice not to mix conventions throughout a project, as it can be a blocker for merging even if the code is functionally fine.

A minor point to make but GMP really is much faster! Not opposed to introducing bcmath support in any case, but perhaps a suggestion in the composer file (it pops up during the install) to try use gmp if possible?

Looks there's something wrong with coveralls, I'm sure there's a stable version available?

Anyway, code looks good, and is fairly well covered. Looks like you could remove the duplicate declaration of isNegative? It's on the base class, but overrided on each implementation - it should be abstract, or, remove the implementation since compare is available on each?

Update coveralls dependency, add GMP as a suggestion in the Composer file and remove the generic isNegative implementation.
@nathanntg
Copy link
Contributor Author

@afk11 Oops, good catch regarding the tabs.

Thanks for the other feedback, I have incorporated it:

  • Updated coveralls requirement to the stable version (2.0).
  • Removed the isNegative implementation, since both subclasses offer their own.

$a = BigInteger::create(-8888);
$this->assertSame(-8888, $a->toInteger());

$a = BigInteger::create(PHP_INT_MAX);
Copy link
Collaborator

@afk11 afk11 Mar 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you do it with this?

$a = BigInteger::create('123897123987123971293871298371293918237812739127398');

It's just as likely a codepath could use toInteger on such a number - maybe the implementations should refuse if the value is above PHP_INT_MAX (an exception)?

Not sure of the effect of calling the functions as it is - would it truncate to PHP_INT_MAX? Maybe a test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the gmp_intval truncates to PHP_INT_MAX. I am of two minds about it.

Originally, I figured that it is up to the caller to only as for an integer when it can be represented. I added some checks and will now throw an exception, but such checks may be overkill and introduce a performance hit.

@afk11
Copy link
Collaborator

afk11 commented Mar 10, 2018

@nathanntg thanks!

on another note, I wonder what your thoughts are applying return type hints? Functions documenting self could probably typehint BigInteger, perhaps the parameters too? No big deal if we don't get them in, but could be nice :)

Ensure properly formatted string, when passing a string in. Separate code path for integers and strings, just to be more explicit in types.

Throws an exception if receiving an invalid string to the create method.

Throws an exception if converting to integer, and the value can not fit in a PHP integer.
@nathanntg
Copy link
Contributor Author

Makes sense, I went ahead and switched the type hints to be explicit (BigInteger).

@fgrosse
Copy link
Owner

fgrosse commented Mar 14, 2018

Hey @nathanntg thanks for the PR and @afk11 for the first review. As usual I'm kept quite busy during the day but I want to take a look this weekend.

Since I am not doing any active PHP development anymore I will first have to setup everything. I was wondering if @afk11 would be interested in commit rights to the repository so we can streamline pull requests a bit and also open up future development of the project. Any thoughts on this?

@afk11
Copy link
Collaborator

afk11 commented Mar 14, 2018

hey @fgrosse! I'd be happy to help with maintaining things - thanks for the offer!

I have had some experience contributing to and using this library, though I am certainly no expert on ASN.1. That said - extra commit rights does hedge against the bus factor, and I can certainly keep things moving as more people work on the project.

It's happens I've been in a similar position with the phpecc project, where I generally just help PR's get merged, maintain a release schedule as required, occasional light touch maintenance, and aim to avoid BC breaks since we don't have time for that :)

@fgrosse
Copy link
Owner

fgrosse commented Mar 31, 2018

Ok, so it took me a bit longer than expected but I finally took the time to review this change. I'm gonna merge this as version 2.1.0 in a couple of minutes.

Thanks again for the contribution and thanks for afk11 for the review :)

@fgrosse fgrosse merged commit 9d33d38 into fgrosse:master Mar 31, 2018
fgrosse added a commit that referenced this pull request Mar 31, 2018
Add support for bcmath extension

Merges pull request #68 by Nathan Perkins
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants