From 6560353cb02deccf0409e41eae652fcbdb616ae9 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Fri, 4 Nov 2011 16:56:25 +1100 Subject: [PATCH] Add some simple checksum algorithms * adler * bsdsum * crc * fletcher --- Makefile.am | 7 ++++++ adler.cpp | 30 ++++++++++++++++++++++++ adler.hpp | 28 +++++++++++++++++++++++ bsdsum.cpp | 35 ++++++++++++++++++++++++++++ bsdsum.hpp | 28 +++++++++++++++++++++++ crc.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++ crc.hpp | 29 ++++++++++++++++++++++++ fletcher.hpp | 44 +++++++++++++++++++++++++++++++++++ test/.gitignore | 1 + test/Makefile.am | 4 ++++ test/checksum.cpp | 32 ++++++++++++++++++++++++++ 11 files changed, 296 insertions(+) create mode 100644 adler.cpp create mode 100644 adler.hpp create mode 100644 bsdsum.cpp create mode 100644 bsdsum.hpp create mode 100644 crc.cpp create mode 100644 crc.hpp create mode 100644 fletcher.hpp create mode 100644 test/checksum.cpp diff --git a/Makefile.am b/Makefile.am index 9db11916..1a05dbb6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,12 +7,18 @@ AM_CXXFLAGS = $(BOOST_CPPFLAGS) $(COMMON_CXXFLAGS) SUBDIRS = test UTIL_FILES = \ + adler.hpp \ + adler.cpp \ annotations.hpp \ backtrace.hpp \ bitwise.cpp \ bitwise.hpp \ + bsdsum.hpp \ + bsdsum.cpp \ colour.cpp \ colour.hpp \ + crc.cpp \ + crc.hpp \ debug.cpp \ debug.hpp \ enable_if.hpp \ @@ -24,6 +30,7 @@ UTIL_FILES = \ extent.hpp \ fixed.cpp \ fixed.hpp \ + fletcher.hpp \ float.cpp \ float.hpp \ fwd.hpp \ diff --git a/adler.cpp b/adler.cpp new file mode 100644 index 00000000..8f844300 --- /dev/null +++ b/adler.cpp @@ -0,0 +1,30 @@ +/* + * This file is part of libgim. + * + * Waif is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Waif is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2010 Danny Robson + */ + +#include "adler.hpp" + +#include "debug.hpp" +#include "fletcher.hpp" + +static const unsigned MODULUS = 65521; + +uint32_t +adler32 (const void* restrict _data, size_t _size) + { return fletcher<32, MODULUS, 1, 0> (_data, _size); } + diff --git a/adler.hpp b/adler.hpp new file mode 100644 index 00000000..e76a9670 --- /dev/null +++ b/adler.hpp @@ -0,0 +1,28 @@ +/* + * This file is part of libgim. + * + * Waif is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Waif is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2010 Danny Robson + */ + +#ifndef __UTIL_ADLER_HPP +#define __UTIL_ADLER_HPP + +#include +#include + +extern uint32_t adler32(const void* restrict, size_t); + +#endif diff --git a/bsdsum.cpp b/bsdsum.cpp new file mode 100644 index 00000000..016e32fb --- /dev/null +++ b/bsdsum.cpp @@ -0,0 +1,35 @@ +/* + * This file is part of libgim. + * + * Waif is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Waif is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2010 Danny Robson + */ + +#include "bsdsum.hpp" + + +uint16_t +bsdsum (const void *restrict _data, size_t size) { + const uint8_t *restrict data = static_cast (data); + uint16_t accum = 0; + + for (size_t i = 0; i < size; ++i) { + accum = (accum >> 1) | ((accum & 0x1) << 15); + accum += data[i]; + } + + return accum; +} + diff --git a/bsdsum.hpp b/bsdsum.hpp new file mode 100644 index 00000000..c1d80e51 --- /dev/null +++ b/bsdsum.hpp @@ -0,0 +1,28 @@ +/* + * This file is part of libgim. + * + * Waif is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Waif is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2010 Danny Robson + */ + +#ifndef __UTIL_BSDSUM_HPP +#define __UTIL_BSDSUMP_HPP + +#include +#include + +uint16_t bsdsum (const void *restrict, size_t); + +#endif diff --git a/crc.cpp b/crc.cpp new file mode 100644 index 00000000..8d26f0ed --- /dev/null +++ b/crc.cpp @@ -0,0 +1,58 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2011 Danny Robson + */ + +#include "crc.hpp" + +#include "debug.hpp" +#include "endian.hpp" + +uint32_t +crc32 (const void *restrict, size_t) { + not_implemented (); + + /* + const uint8_t *restrict data = static_cast (_data); + static const uint32_t POLYNOMIAL = hton (static_cast(0x04C11DB7)); + + uint64_t bits = 0; + unsigned int i = 0; + + if (size == 0) + return POLYNOMIAL; + + switch (size) { + default: bits |= static_cast(data[3]) << 32U; + case 3: bits |= static_cast(data[2]) << 40U; + case 2: bits |= static_cast(data[1]) << 48U; + case 1: bits |= static_cast(data[0]) << 56U; + } + + for (size_t i = 0; i < size; ++i) { + for (unsigned j = 0; j < 32; ++j) { + bool mix = bits 0x7000000000000000ULL; + bits <<= 1; + + if (mix) + bits ^= POLYNOMIAL << 32; + } + + + } + */ +} diff --git a/crc.hpp b/crc.hpp new file mode 100644 index 00000000..f6979b12 --- /dev/null +++ b/crc.hpp @@ -0,0 +1,29 @@ +/* + * This file is part of libgim. + * + * libgim is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * libgim is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2011 Danny Robson + */ + +#ifndef __UTIL_CRC_HPP +#define __UTIL_CRC_HPP + +#include +#include + +uint32_t crc32 (const void *restrict, size_t); + +#endif + diff --git a/fletcher.hpp b/fletcher.hpp new file mode 100644 index 00000000..a63ebcaa --- /dev/null +++ b/fletcher.hpp @@ -0,0 +1,44 @@ +/* + * This file is part of libgim. + * + * Waif is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Waif is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with libgim. If not, see . + * + * Copyright 2010 Danny Robson + */ + +#ifndef __UTIL_FLETCHER_HPP +#define __UTIL_FLETCHER_HPP + +#include "types.hpp" + +#include +#include + +template +typename bits_type::uint +fletcher (const void *restrict _data, size_t size) { + const uint8_t *restrict data = static_cast (_data); + typename bits_type::uint A = INITIAL_A, + B = INITIAL_B; + + for (size_t i = 0; i < size; ++i) { + A = (A + data[i]) % MODULUS; + B = (A + B) % MODULUS; + } + + return (B << (BITS / 2)) | A; +} + +#endif + diff --git a/test/.gitignore b/test/.gitignore index 90d95a58..65f608cc 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,3 +1,4 @@ +/adler /backtrace* /float* /hton* diff --git a/test/Makefile.am b/test/Makefile.am index f9b97c77..113d4bc1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -9,6 +9,7 @@ AM_LDFLAGS = $(COMMON_LDFLAGS) TEST_BIN = \ backtrace \ + checksum \ float \ hton \ ip \ @@ -27,6 +28,9 @@ backtrace_CPPFLAGS = $(COMMON_CXXFLAGS) backtrace_LDADD = $(builddir)/../libutil.la backtrace_SOURCES = backtrace.cpp +checksum_LDADD = $(builddir)/../libutil.la +checksum_SOURCES = checksum.cpp + float_LDADD = $(builddir)/../libutil.la float_SOURCES = float.cpp diff --git a/test/checksum.cpp b/test/checksum.cpp new file mode 100644 index 00000000..dbb6315c --- /dev/null +++ b/test/checksum.cpp @@ -0,0 +1,32 @@ + +#include "adler.hpp" +#include "bsdsum.hpp" +#include "types.hpp" + +#include +#include + +using namespace std; + +static const char *ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +static const struct { + uint32_t adler; + uint16_t bsd; + + const char *data; + size_t size; +} TESTS[] = { + { 0xDF5B150C, 0x52FB, ALPHABET, strlen (ALPHABET) } +}; + + +int +main (int, char**) { + for (unsigned i = 0; i < elems (TESTS); ++i) { + check_eq (TESTS[i].adler, adler32 (TESTS[i].data, TESTS[i].size)); + check_eq (TESTS[i].bsd, bsdsum (TESTS[i].data, TESTS[i].size)); + } + + return EXIT_SUCCESS; +}