package de.tu_darmstadt.tk.SmartHomeNetworkSim.core.util; /** * Class for calculating checksums, taken from stackoverflow * * * @author Andreas T. Meyer-Berg */ public class ICMPv6Checksum { /** * Calculate the Internet Checksum of a buffer (RFC 1071 - * http://www.faqs.org/rfcs/rfc1071.html) Algorithm is 1) apply a 16-bit 1's * complement sum over all octets (adjacent 8-bit pairs [A,B], final odd * length is [A,0]) 2) apply 1's complement to this final sum * * Notes: 1's complement is bitwise NOT of positive value. Ensure that any * carry bits are added back to avoid off-by-one errors * * * @param buf * The message * @return The checksum * @author Gary Rowe * @see https://stackoverflow.com/questions/4113890/how-to-calculate-the-internet-checksum-from-a-byte-in-java */ public static long calculateChecksum(byte[] buf) { int length = buf.length; int i = 0; long sum = 0; long data; // Handle all pairs while (length > 1) { // Corrected to include @Andy's edits and various comments on Stack // Overflow data = (((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF)); sum += data; // 1's complement carry bit correction in 16-bits (detecting sign // extension) if ((sum & 0xFFFF0000) > 0) { sum = sum & 0xFFFF; sum += 1; } i += 2; length -= 2; } // Handle remaining byte in odd length buffers if (length > 0) { // Corrected to include @Andy's edits and various comments on Stack // Overflow sum += (buf[i] << 8 & 0xFF00); // 1's complement carry bit correction in 16-bits (detecting sign // extension) if ((sum & 0xFFFF0000) > 0) { sum = sum & 0xFFFF; sum += 1; } } // Final 1's complement value correction to 16-bits sum = ~sum; sum = sum & 0xFFFF; return sum; } }