/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.nikobus.internal.util; import javax.xml.bind.DatatypeConverter; import org.apache.commons.lang.StringUtils; /** * Utility to calculate a Nikobus checksums. * * @author Davy Vanherbergen * @since 1.3.0 */ public class CRCUtil { private static final int CRC_INIT = 0xFFFF; private static final int POLYNOMIAL = 0x1021; /** * Calculate the CRC16-CCITT checksum on the input string and return the * input string with the checksum appended. * * @param input * String representing hex numbers. * @return input string + CRC. */ public static String appendCRC(String input) { if (input == null) { return null; } int check = CRC_INIT; for (byte b : DatatypeConverter.parseHexBinary(input)) { for (int i = 0; i < 8; i++) { if (((b >> (7 - i) & 1) == 1) ^ ((check >> 15 & 1) == 1)) { check = check << 1; check = check ^ POLYNOMIAL; } else { check = check << 1; } } } check = check & CRC_INIT; String checksum = StringUtils.leftPad(Integer.toHexString(check), 4, "0"); return (input + checksum).toUpperCase(); } /** * Calculate the second checksum on the input string and return the * input string with the checksum appended. * * @param input * String representing a nikobus command. * @return input string + CRC. */ public static String appendCRC2(String input) { int check = 0; for (byte b : input.getBytes()) { check = check ^ b; for (int i = 0; i < 8; i++) { if (((check & 0xff) >> 7) != 0) { check = check << 1; check = check ^ 0x99; } else { check = check << 1; } check = check & 0xff; } } return input + StringUtils.leftPad(Integer.toHexString(check), 2, "0").toUpperCase(); } }