I am trying to find a way to "hash" the contents of an XML file. At the root of this is a need to compare some text nodes that are passed in to text nodes that I am expecting to make sure that the checksum is the same. The passed-in text nodes have returned from a form submission and I need to ensure that they were not changed (within reason, ruling out collisions).
The architecture is horrible, so please don't ask about it! I am locked in to a given implementation of sharepoint with some very bad custom code that I need to work around.
Is there a well-performing checksum/hash function that can be implemented? I would need to check about 100 text nodes.
Sounds like you need a position-dependent checksum. Are you asking for an XSLT implementation, or just the algorithm?
Here is an implementation of Fletcher's checksum in C, which should not be very hard to port to XSLT.
Update: Below is an XSLT 2.0 adaptation of Fletcher's checksum. Whether it's fast enough, depends on the size of your data and the amount of time you have. I'd be interested to hear how your tests go. To optimize, I would attempt to change
xs:integer
toxs:int
.Note that I have substituted plain addition for the bitwise OR (
|
) of the implementation I linked to above. I'm not really qualified to analyze the ramifications of this change in regard to uniformity or non-invertibility, but it seems OK as long as you don't have a smart hacker trying to maliciously bypass your checksum checks.Do note that because of the above change, this implementation will not give the same results as true implementations of Fletcher's checksum (@MDBiker). So you can't compare the output of this function with that of Java's Fletcher16, for example. However it will always return the same result for the same input (it's deterministic), so you can compare the output of this function on two text strings.
The output:
A note on usage: You said you needed to run checksum on "the contents of an XML file. At the root of this is a need to compare some text nodes". If you pass a text node to foo:checksum(), it will work fine: its string value will be extracted.
FYI, I ran a performance test, to calculate the checksum of text nodes in a 535KB XML input file. Here was the initial template I used:
It finished in 0.8s, using Saxon PE.
Alternatively:
If the amount of text is not very large, it would probably be faster and more accurate to simply compare the strings themselves (instead of checksums) to each other. But maybe you can't get access to both text nodes at the same time, due to your architecture restrictions... I'm not clear on that from your description.