]> git.basschouten.com Git - openhab-addons.git/blob
f294c6311e2baa30c6c8f5e5c7908947e840e254
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.nikobus.internal.utils;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.openhab.core.util.HexUtils;
18
19 /**
20  * The {@link CRCUtil} class defines utility functions to calculate CRC used by the Nikobus communication protocol.
21  *
22  * @author Davy Vanherbergen - Initial contribution
23  * @author Boris Krivonog - Removed dependency to javax.xml.bind.DatatypeConverter
24  */
25 @NonNullByDefault
26 public class CRCUtil {
27
28     private static final int CRC_INIT = 0xFFFF;
29
30     private static final int POLYNOMIAL = 0x1021;
31
32     /**
33      * Calculate the CRC16-CCITT checksum on the input string and return the
34      * input string with the checksum appended.
35      *
36      * @param input
37      *            String representing hex numbers.
38      * @return input string + CRC.
39      */
40     public static @Nullable String appendCRC(@Nullable String input) {
41         if (input == null) {
42             return null;
43         }
44
45         int check = CRC_INIT;
46
47         for (byte b : HexUtils.hexToBytes(input)) {
48             for (int i = 0; i < 8; i++) {
49                 if (((b >> (7 - i) & 1) == 1) ^ ((check >> 15 & 1) == 1)) {
50                     check = check << 1;
51                     check = check ^ POLYNOMIAL;
52                 } else {
53                     check = check << 1;
54                 }
55             }
56         }
57
58         check = check & CRC_INIT;
59         String checksum = Utils.leftPadWithZeros(Integer.toHexString(check), 4);
60         return (input + checksum).toUpperCase();
61     }
62
63     /**
64      * Calculate the second checksum on the input string and return the
65      * input string with the checksum appended.
66      *
67      * @param input
68      *            String representing a nikobus command.
69      * @return input string + CRC.
70      */
71     public static String appendCRC2(String input) {
72         int check = 0;
73
74         for (byte b : input.getBytes()) {
75
76             check = check ^ b;
77
78             for (int i = 0; i < 8; i++) {
79
80                 if (((check & 0xff) >> 7) != 0) {
81                     check = check << 1;
82                     check = check ^ 0x99;
83                 } else {
84                     check = check << 1;
85                 }
86                 check = check & 0xff;
87             }
88         }
89
90         return input + Utils.leftPadWithZeros(Integer.toHexString(check), 2).toUpperCase();
91     }
92 }