Skip to content

Instantly share code, notes, and snippets.

@bryc
Last active December 15, 2022 09:03
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryc/8a0885a4be58b6bbf0ec54c7758c0841 to your computer and use it in GitHub Desktop.
Save bryc/8a0885a4be58b6bbf0ec54c7758c0841 to your computer and use it in GitHub Desktop.
CHECKSUMS!
// BSD-16
// From: en.wikipedia.org/wiki/BSD_checksum
function bsd16(data) {
for(var i = 0, c = 0; i < data.length; i++) {
c = (c>>1) + ((c&1) << 15);
c += data[i];
c &= 0xffff;
}
return c;
}
// Fletcher-16
// Modulo 255 version, might be incorrect/incomplete. From: en.wikipedia.org/wiki/Fletcher's_checksum
function fletcher16a(data) {
var a = 0, b = 0;
for (var i = 0; i < data.length; i++) {
a = (a + data[i]) % 255;
b = (b + a) % 255;
}
return a | (b << 8);
}
// Fletcher-16
// More complicated version
function fletcher16(buf) {
var sum1 = 0xff, sum2 = 0xff;
var i = 0;
var len = buf.length;
while (len) {
var tlen = len > 20 ? 20 : len;
len -= tlen;
do {
sum2 += sum1 += buf[i++];
} while (--tlen);
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
}
sum1 = (sum1 & 0xff) + (sum1 >> 8);
sum2 = (sum2 & 0xff) + (sum2 >> 8);
return sum2 << 8 | sum1;
}
// Fletcher-32
// May operate on 16-bit words (not bytes).
function fletcher32(data) {
var _sum1 = 0xffff, _sum2 = 0xffff;
var words = data.length;
var dataIndex = 0;
while (words) {
var tlen = words > 359 ? 359 : words;
words -= tlen;
do {
_sum2 += _sum1 += data[dataIndex++];
} while (--tlen);
_sum1 = ((_sum1 & 0xffff) >>> 0) + (_sum1 >>> 16);
_sum2 = ((_sum2 & 0xffff) >>> 0) + (_sum2 >>> 16);
}
_sum1 = ((_sum1 & 0xffff) >>> 0) + (_sum1 >>> 16);
_sum2 = ((_sum2 & 0xffff) >>> 0) + (_sum2 >>> 16);
return ((_sum2 << 16) >>> 0 | _sum1) >>> 0;
}
// Adler-32
function adler32(data) {
var a = 1, b = 0;
for (var i = 0; i < data.length; i++) {
a = (a + data[i]) % 65521;
b = (b + a) % 65521;
}
return a | (b << 16);
}
// FNV-32 (0 = FNV-0, 1 = FNV-1, 2 = FNV-1a)
function fnv32(data, mode = 2) {
var hash = mode ? 0x811c9dc5 : 0;
for (var i = 0; i < data.length; i++) {
(mode == 2) && (hash ^= data[i]);
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
(mode < 2) && (hash ^= data[i]);
}
return hash >>> 0;
}
/*
Checksum algos:
# 8-bit checksum - unsigned/mod(256)
0x40 = (0xCA + 0xFE + 0xBA + 0xBE) & 0xFF
# 8-bit checksum - one's complement
0xBF = ~(0xCA + 0xFE + 0xBA + 0xBE) & 0xFF
# 8-bit checksum - two's complement
0xC0 = (~(0xCA + 0xFE + 0xBA + 0xBE) + 1) & 0xFF
:8-bit checksum - two's complement (variation)
0xC0 = -(0xCA + 0xFE + 0xBA + 0xBE) & 0xFF
# 8-bit checksum - xor
0x30 = 0xCA ^ 0xFE ^ 0xBA ^ 0xBE
:8-bit checksum - xor (one's compliment?)
0x31 = (0xCA ^ 0xFE ^ 0xBA ^ 0xBE) ^ 1
:8-bit checksum - xor (variation)
0xCF = (0xCA ^ 0xFE ^ 0xBA ^ 0xBE) ^ 0xFF
----
notes: both xor and two's compliment sum are referred to Longitudinal parity check, confusingly.
----
:16-bit checksum - (ipv4)
~(0x4500+0x0073+0x0000+0x4000+0x4011+0xc0a8+0x0001+0xc0a8+0x00c7) % 0xFFFF & 0xFFFF
*/
/*
Internet Protocol Header Checksum
Implements the checksum algorithm used in IPv4 packets (TCP/UDP). Has the
property of being able to verify data quickly by summing the block
that includes the checksum. Result ends up being 0xFFFF, which
historically was compared against 0 for performance reasons.
" The checksum algorithm is:
The checksum field is the 16 bit one's complement of the one's
complement sum of all 16 bit words in the header. For purposes of
computing the checksum, the value of the checksum field is zero."
From: https://tools.ietf.org/html/rfc760#page-11
More info: https://en.wikipedia.org/wiki/IPv4_header_checksum
https://tools.ietf.org/html/rfc1071
*/
var data = [ // checksum: 0xb861
0x45, 0x00, 0x00, 0x73, 0x00, 0x00, 0x40, 0x00,
0x40, 0x11, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, 0x00, 0xc7
];
function IPv4(data) {
for(var sum = 0, i = 0; i < data.length; i += 2)
{
var digit = (data[i] << 8) + data[i + 1];
sum = (sum + digit) % 65535;
}
// a bitwise method of carrying the bits:
//while (sum >> 16) sum = (sum & 0xFFFF)+(sum >> 16);
return (~sum) & 0xFFFF;
}
IPv4(data).toString(16);
// not a checksum, but no other place to put it.
var estimateFileSize = function(songLength) {
var bitRate = 192;
var time = songLength.split(":");
var seconds = parseInt(time[1],10) + (parseInt(time[0],10) * 60);
var sizeMB = (( bitRate * 1024 * seconds) / 8 / 1024 / 1024).toFixed(2);
return "A track with the length of "+songLength+" and a bitrate of "+bitRate+" is "+sizeMB+"MB";
}
// bsck - My original simple checksum algo
function bsck(data) {
for(var i = 0, sum = 1; i < data.length; i++) {
sum = (data[i] + sum + (sum<<1)) >>> 0;
}
return sum;
}
// Simple checksum. stolen from some forum, looked interesting. mine now.
function simpsum(data) {
for(var i = 0, sum = 1; i < data.length; i++) {
sum = (sum << 1) ^ data[i];
// sum += (sum << 1) ^ data[i]; // better?
}
return sum;
}
// 'Improved' and simplified version of BSD-16.
function bsd16a(data) {
for(var i = 0, sum = 255; i < data.length; i++){
sum += (sum>>1)+((sum)<<15) + data[i];
sum &= 0xFFFF;
}
return sum;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment