Article printed from:
`https://blog.jermdavis.dev/posts/2021/repeatable-delays-from-data`

C#
~2 min. read

I had an interesting discussion recently, about how some code could calculate a "random" but deterministic numeric value based on some data. This made me think of the classic old concept of "checksums" as a possible solution. Here's what I was thinking about:

A common code pattern where users need to enter identity data, is to add a digit to the end which represents a checksum. The last digit of a card or account number is a common place to find this – the last digit is computed from the preceding ones to give a reasonable test that all the numbers have been entered correctly. There are a collection of common algorithms for doing this – but I was considering stealing the one from "UPC" barcodes. There, you start with a multi-digit number and:

- Add together the values of the odd digits
- Multiply that value by three
- Add together the values of the even digits
- Add together the odd and even sums
- Take the remainder of dividing that sum by 10
- If that's not zero subtract it from 10

So you end up with a number that's based on the source, and that will change if the source changes.

var name = System.Net.Dns.GetHostName();

And that can be used to work out a value for the delay:

var delay = CalculateDelay(name);

In simple code, calculating that function looks like:

int CalculateDelay(string name) { var integers = name.ToLower().Select(c => (int)c); var odds = integers.Where((c, i) => i % 2 != 0).Sum() * 3; var evens = integers.Where((c, i) => i % 2 == 0).Sum(); var sum = (odds + evens) % 10; if(sum > 0) { sum = 10 - sum; } return sum; }

It's probably not ideal to be adding numbers as large as this using the UPC algorithm, but it seems to work. So for any machine name we'll end up with a delay value from zero to ten. Taking a set of possible pod names where the code might run, the outputs look like:

cm-ae411c6fd6-yttss -> 8s cm-0625876ce1-ptpdo -> 4s cm-33b99ec5f0-hklfy -> 3s cm-d10b43095b-ofxnf -> 9s cm-b61a9a47b4-rhnrz -> 7s cm-182f39205e-qbgat -> 4s cm-99f646c98d-hbfye -> 0s cm-579c2e34d5-tndcc -> 9s cm-5033a8d1bb-dhrnr -> 5s cm-504e5ccdae-oygnu -> 9s cm-8ce2fdf292-ynwid -> 6s cm-245fd1273e-zwdia -> 2s cm-6e2131b125-wcigd -> 4s cm-135354ddf2-qlhjc -> 1s cm-fc84f3b0f6-fifbq -> 4s cm-3743d96305-fxtto -> 5s cm-d1e9220abd-emvke -> 2s cm-4630ff27d7-qfubm -> 6s cm-f4653da2ef-dcehw -> 3s cm-6f34d6f2c9-ritip -> 9s

That gives a reasonable spread of values for whatever string we the code starts from, and they're repeatable rather than random.

↑ Back to top