Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Split your string into three shorter strings (if not divisible by three, the last one will be longer than the other two). Run your "short" algorithm on each, and concatenate the results.</p> <p>I could write the code but based on the quality of the question I think you can take it from here!</p> <p>EDIT: It turns out that that advice is not enough. There is a serious flaw in your original CRC16 code - namely the line that says:</p> <pre><code>j = Val("&amp;H" + Mid(txt, nC, 2)) </code></pre> <p>This only handles text that can be interpreted as hex values: lowercase and uppercase letters are the same, and anything after F in the alphabet is ignored (as far as I can tell). That anything good comes out at all is a miracle. If you replace the line with</p> <pre><code>j = asc(mid(txt, nC, 1)) </code></pre> <p>Things work better - every ASCII code at least starts out life as its own value.</p> <p>Combining this change with the proposal I made earlier, you get the following code:</p> <pre><code>Function hash12(s As String) ' create a 12 character hash from string s Dim l As Integer, l3 As Integer Dim s1 As String, s2 As String, s3 As String l = Len(s) l3 = Int(l / 3) s1 = Mid(s, 1, l3) ' first part s2 = Mid(s, l3 + 1, l3) ' middle part s3 = Mid(s, 2 * l3 + 1) ' the rest of the string... hash12 = hash4(s1) + hash4(s2) + hash4(s3) End Function Function hash4(txt) ' copied from the example Dim x As Long Dim mask, i, j, nC, crc As Integer Dim c As String crc = &amp;HFFFF For nC = 1 To Len(txt) j = Asc(Mid(txt, nC)) ' &lt;&lt;&lt;&lt;&lt;&lt;&lt; new line of code - makes all the difference ' instead of j = Val("&amp;H" + Mid(txt, nC, 2)) crc = crc Xor j For j = 1 To 8 mask = 0 If crc / 2 &lt;&gt; Int(crc / 2) Then mask = &amp;HA001 crc = Int(crc / 2) And &amp;H7FFF: crc = crc Xor mask Next j Next nC c = Hex$(crc) ' &lt;&lt;&lt;&lt;&lt; new section: make sure returned string is always 4 characters long &gt;&gt;&gt;&gt;&gt; ' pad to always have length 4: While Len(c) &lt; 4 c = "0" &amp; c Wend hash4 = c End Function </code></pre> <p>You can place this code in your spreadsheet as <code>=hash12("A2")</code> etc. For fun, you can also use the "new, improved" hash4 algorithm, and see how they compare. I created a pivot table to count collisions - there were none for the <code>hash12</code> algorithm, and only 3 for the <code>hash4</code>. I'm sure you can figure out how to create <code>hash8</code>, ... from this. The "no need to be unique" from your question suggests that maybe the "improved" <code>hash4</code> is all you need.</p> <p>In principle, a four character hex should have 64k unique values - so the chance of two random strings having the same hash would be 1 in 64k. When you have 400 strings, there are 400 x 399 / 2 "possible collision pairs" ~ 80k opportunities (assuming you had highly random strings). Observing three collisions in the sample dataset is therefore not an unreasonable score. As your number of strings N goes up, the probability of collisions goes as the square of N. With the extra 32 bits of information in the hash12, you expect to see collisions when N > 20 M or so (handwaving, in-my-head-math).</p> <p>You can make the hash12 code a little bit more compact, obviously - and it should be easy to see how to extend it to any length.</p> <p>Oh - and one last thing. If you have RC addressing enabled, using <code>=CRC16("string")</code> as a spreadsheet formula gives a hard-to-track <code>#REF</code> error... which is why I renamed it <code>hash4</code></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload