Change finance.routingNumber() to take an optional boolean argument which forces the result to attempt to correspond to a real financial institution. #3290
Labels
c: feature
Request for new feature
m: finance
Something is referring to the finance module
s: needs decision
Needs team/maintainer decision
s: waiting for user interest
Waiting for more users interested in this feature
Problem Description
There are rules regarding what is and isn't possibly a legitimate routing number according to the American Bankers Association and/or the Federal Reserve. As of now, faker complies with only a part of this ruleset (the check digit validation), but based on a few tests I ran locally, the Federal Reserve Routing Symbol (the first 4 digits) and the Institution Identifier (the next 4 digits) of FinanceModule.routingNumber have failed to correspond to an actual, usable-in-the-wild value.
Note: This proposal is primarily concerned with modifications that would produce a routing number with a valid Federal Reserve Routing Symbol (first 4 digits), and not the Institution Identifier (next 4 digits). Also note that, despite using the words "in the wild", that is not the goal of this proposal, but rather to produce a routing number that is significantly closer to what a real, usable routing number would be than what faker currently produces.
Suggested solution (if the proposed data meets all requirements for licensing/copyright)
Link to "Proposed Data"
In FinanceModule.routingNumber():
digits [0-3] (Federal Reserve Routing Symbol) = Pull from a static lookup table derived from the proposed data.
digits [4-7] (Institution Identifier) = 4 random digits. (I am not proposing to attempt to solve this problem.)
digits[8] (Check Digit) = derived from digits[0-7]
Alternative (if the proposed data does NOT meet requirements for licensing/copyright)
digits [0-1] (Federal Reserve District Identitifer) = Random number between 1 and 12, left-padded with a zero. This would correspond to the 12 federal reserve banks, and would be better than nothing at all.
Note: '00' is reserved for U.S. government use and, in my opinion, should not be allowed to be produced as [I assume] almost anybody using this library is not going to be concerned with routing numbers starting with '00', but that may be a false assumption; you tell me.
digits [2-3] (Federal Reserve Branch Office City Identifier) = 2 random digits, left-padded with a zero.
Note: The wikipedia page for ABA Routing Numbers lists what appears to be all of these, but no source is cited, and therefore cannot be used as a source of truth. Furthermore, it lists a 3-digit value '101' as belonging to American territories such as American Samoa, Puerto Rico, Guam, etc., which doesn't make much sense. Also, this isn't strictly necessary for the proposal, anyway.
The rest is the same as the primary proposed solution:
digits [4-7] (Institution Identifier) = 4 random digits.
digits[8] (Check Digit) = derived from digits[0-7]
Additional context
The trouble with implementing a feature like this is that technically, the "rules" surrounding what does or does not constitute a routing number which corresponds to a real financial institution are always in flux. However, practically, the majority of these rules either have never changed since the Federal Reserve's inception in 1913, as far as I can tell anyway (e.g. routing numbers starting in '80' for traveler's checks), or have not changed in such a long time that they can be effectively treated as though they've never changed (e.g. "thrift" institutions codes have not changed since the mid-1980s). Therefore, even if the updates to the rules vs this library were not fully in sync, there would still be a vastly improved chance of getting a valid, real routing number than otherwise. The main part which I believe can be improved is that of the Federal Reserve Routing Symbol, which is simply the first 4 characters of the routing number, which is further broken down as the first 2 characters designating the Federal Reserve District and the second 2 characters designating the city of the reserve branch within that district. These do not change very often (I'm not entirely sure, after some research, the last time they have).
You can check validation here (https://routingnumber.aba.com/Search1.aspx) to see for yourself (one simple test is to use '522814402' (the routing number given in the comment above the function definition), but this is a business and using that API is of course not viable for an open-source product. I mentioned this simply as a quick way to verify the legitimacy of the need for this feature.
And just in case this point is raised, I suppose I can address it with my own opinion now. It is arguable that since faker's purpose is to produce fake data anyway, it shouldn't need to be a real financial institution at all. However, I am of the opinion that since test code will inevitably use portions of production code, and it cannot be assumed that that production code was written in a way that makes it feasible to isolate its mechanics from its semantics, it should not be a concern for those using this library to need to differentiate between a valid (real-world) routing number and an invalid routing number that simply passes check digit validation.
Furthermore, it may be best simply to augment the existing functionality of routingNumber() to just return one with either its first 4 digits from the lookup table or the first 2 constrained to between '01' - '12', and not have an optional boolean argument at all. After all, using the proposed boolean switch should simply produce a routing number that is a member of a subset of all the routing numbers that it currently produces, so any valid routing number when using the switch should also be among the set of those produced without it.
The text was updated successfully, but these errors were encountered: