This heavily draws from my similar SHA1 similarities article.
Following my SHA1 work, I wrote three implementations of SHA256, and two of SHA224, in preparing for a comprehensive SHA. I'd already planned to compare the final works, but these intermediate results can also prove suitably interesting. Of course, read my articles concerning these three beforehand.
As with the SHA1, my APL still operated solely on bit vectors; it was quite a large seventeen lines, disregarding the constants and function headers and footers. The APL was perhaps the most haphazard of the three, as I merely needed it working, and its brevity allowed it to be so ugly, in hindsight. It's also because of this nature my APL was entirely unsuited to the digest-transformation required; it's brief, but not transparent, as with those others. Importantly, this APL was easiest to finish.
Again as with the SHA1, my Common Lisp operated solely in terms of octets. I'm also least-satisfied with it. It's greater than two hundred lines, and my overall design is a great improvement over the SHA1, but Common Lisp isn't suited to the problem, as APL is, nor does it permit the fine control by typing which Ada permits. I extended the basic design of the SHA1 through further use of CLOS, with fear of performance concerns I'd later find warranted; as this wasn't intended to be a final result, I wasn't nearly so aggressive with macros as I should've been; I experimented with an implementation for PAD which shunned conditional code, but it was merely more difficult to write. I'm not strictly dissatisfied with my CLOS protocol I've devised here, but I only regard this design as experimental.
The Ada design directly followed from the SHA1, incorporating bits, octets, and words. The Ada came far after the other two, because it was difficult for me to write, owing to my inexperience with the language. It's easily the largest, measuring at roughly four hundred and seventy lines large. This has been pleasant, and I'm glad for the experience, as I'm now far more skilled with generics. That primary difference lies in having three varieties of the subprograms for each unit; my Pad design is greatly improved over the rest, as it now accepts a length in terms of the unit being padded, rather than a general bit-length. This greatly simplifies its use and implementation, and came about by my noticing the same general form could be used for padding, which merely places a sigil, zeroes, and a length, were the sigil able to be expressed in terms of the particular unit. This is also trivially reviewed, unlike the other designs. There's not an Ada SHA224, unlike the others, because it was so arduous merely to write this, and I'll need to write the SHA224 only when I put in place the generic machinery the final form will employ. As with my prior, I'm again most satisfied by the Ada design.
It was again a valuable experience, with that APL being closest to the ideal I feel I should be able to pursue, yet practically don't, the Common Lisp being easiest to use in every way, yet laying upon an uneasy line between those two extremes, and the Ada being that most complex and arduous to write, yet remaining practical, and closer to its final ideal, and that which I find to be nicest, overall.