Commit 3ed4f968 authored by Pavel Tvrdík's avatar Pavel Tvrdík
Browse files

Birdtest: Add Fletcher-16 Checksum Tests

parent f594ab67
Loading
Loading
Loading
Loading

lib/fletcher16_test.c

0 → 100644
+180 −0
Original line number Diff line number Diff line
/*
 *	BIRD Library -- Fletcher-16 checksum Tests
 *
 *	(c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
 *	(c) 2015 CZ.NIC z.s.p.o.
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include "test/birdtest.h"
#include "test/birdtest_support.h"	/* REMOVE ME */

#include "lib/fletcher16.h"

struct in {
  u8 *data;
  int count;
};

static u16
straightforward_fletcher16_compute(const char *data)
{
  int count = strlen(data);

  u16 sum1 = 0;
  u16 sum2 = 0;
  int index;

  for(index = 0; index < count; ++index)
  {
    sum1 = (sum1 + data[index]) % 255;
    sum2 = (sum2 + sum1) % 255;
  }

  return (sum2 << 8) | sum1;
}

static u16
straightforward_fletcher16_checksum(const char *data)
{
  u16 csum;
  u8 c0,c1,f0,f1;

  csum = straightforward_fletcher16_compute(data);
  f0 = csum & 0xff;
  f1 = (csum >> 8) & 0xff;
  c0 = 0xff - ((f0 + f1) % 0xff);
  c1 = 0xff - ((f0 + c0) % 0xff);

  return (c1 << 8) | c0;
}

static u16
get_fletcher16_compute(const char *str)
{
  struct fletcher16_context ctxt;

  fletcher16_init(&ctxt);
  fletcher16_update(&ctxt, str, strlen(str));
  u16 f;
  put_u16(&f, fletcher16_compute(&ctxt));
  return f;
}

static u16
get_fletcher16_checksum(const char *str)
{
  struct fletcher16_context ctxt;

  int len = strlen(str);

  fletcher16_init(&ctxt);
  fletcher16_update(&ctxt, str, len);
  u16 f;
  put_u16(&f, fletcher16_final(&ctxt, len, len));
  return f;
}

static int
t_fletcher16_compute(void)
{
  struct in_out {
    char *in;
    u16 out;
  } in_out[] = {
      {
	  .in  = "\001\002",
	  .out = 0x0403,
      },
      {
	  .in  = "",
	  .out = straightforward_fletcher16_compute(""),
      },
      {
	  .in  = "a",
	  .out = straightforward_fletcher16_compute("a"),
      },
      {
	  .in  = "abcd",
	  .out = straightforward_fletcher16_compute("abcd"),
      },
      {
	  .in  = "message digest",
	  .out = straightforward_fletcher16_compute("message digest"),
      },
      {
	  .in  = "abcdefghijklmnopqrstuvwxyz",
	  .out = straightforward_fletcher16_compute("abcdefghijklmnopqrstuvwxyz"),
      },
      {
	  .in  = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
	  .out = straightforward_fletcher16_compute("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
      },
      {
	  .in  = "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
	  .out = straightforward_fletcher16_compute("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
      },
  };

  bt_assert_out_fn_in(get_fletcher16_compute, in_out, "'%s'", "0x%04X");

  return BT_SUCCESS;
}

static int
t_fletcher16_checksum(void)
{
  struct in_out {
    char *in;
    u16 out;
  } in_out[] = {
      {
	  .in  = "\001\002",
	  .out = straightforward_fletcher16_checksum("\001\002"),
      },
      {
	  .in  = "",
	  .out = straightforward_fletcher16_checksum(""),
      },
      {
	  .in  = "a",
	  .out = straightforward_fletcher16_checksum("a"),
      },
      {
	  .in  = "abcd",
	  .out = straightforward_fletcher16_checksum("abcd"),
      },
      {
	  .in  = "message digest",
	  .out = straightforward_fletcher16_checksum("message digest"),
      },
      {
	  .in  = "abcdefghijklmnopqrstuvwxyz",
	  .out = straightforward_fletcher16_checksum("abcdefghijklmnopqrstuvwxyz"),
      },
      {
	  .in  = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
	  .out = straightforward_fletcher16_checksum("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"),
      },
      {
	  .in  = "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
	  .out = straightforward_fletcher16_checksum("12345678901234567890123456789012345678901234567890123456789012345678901234567890"),
      },
  };

  bt_assert_out_fn_in(get_fletcher16_checksum, in_out, "'%s'", "0x%04X");

  return BT_SUCCESS;
}

int
main(int argc, char *argv[])
{
  bt_init(argc, argv);

  bt_test_suite(t_fletcher16_compute, "Fletcher-16 Compute Tests");
  bt_test_suite(t_fletcher16_checksum, "Fletcher-16 Checksum Tests");

  return bt_end();
}