Performance improvements to your implementation

I pulled your implementation and added two performance improvements that seem to add up to about 10% on the sample data. In practice, I suspect they would be even better. In particular, the first change should dramatically improve performance on inputs that are mostly text (as most log messages are) vs. digits. The improvement ideas are:

1. After a reset, skip ahead by MIN_LENGTH and check if the character at that location is a digit (or separator). If not, the entire region from the current index to current index + MIN_LENGTH can be skipped. Furthermore, you can now repeat the test by skipping another MIN_LENGTH and checking again. Repeat until you hit a digit or are past the end of the string. Then resume your regular processing.

This algorithm could be heuristically improved by analyzing the digit content of your logs. So, if the logs typically contain a timestamp, followed by some text, followed by a line number (as in an exception stack trace), it might be beneficial to upon finding a number at (current+MIN_LENGTH) back off 5 characters and check again. The assumption here being you don't have source files over 10k loc, so the backoff gets you out of the line number, if that happens to be where you landed. This backoff would have to be balanced against the extra computation involved, but I think it's still a significant win, because if you get to a non-digit region, you can continue by taking another stride forward.

2. If we save the number of digits masked in the previous mask, then we do not have to remask already masked characters except in the 14- nested in 16-digit number case. This is a significant savings on the test data set, but unlikely to matter much in practice. So, perhaps the reduction in clarity/simplicity isn't worth it.