All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nervousync.security.digest.impl.CRCDigestAdapterImpl Maven / Gradle / Ivy

There is a newer version: 1.2.1
Show newest version
/*
 * Licensed to the Nervousync Studio (NSYC) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.nervousync.security.digest.impl;

import org.nervousync.exceptions.utils.DataInvalidException;
import org.nervousync.security.api.SecureAdapter;
import org.nervousync.security.config.CRCConfig;
import org.nervousync.exceptions.crypto.CryptoException;
import org.nervousync.utils.RawUtils;

import java.nio.ByteOrder;
import java.util.*;

/**
 * 

Symmetric CRC crypto adapter class

*

CRC摘要算法适配器的实现类

* * @author Steven Wee [email protected] * @version $Revision: 1.0.0 $ $Date: Jan 13, 2012 13:50:21 $ */ public final class CRCDigestAdapterImpl extends SecureAdapter { /** * CRC configure * CRC设置 */ private final CRCConfig crcConfig; /** * CRC polynomial * CRC多项式编码 */ private final long polynomial; /** * CRC initialize value * CRC初始值 */ private final long init; /** * CRC check value */ private final long check; /** * CRC mask value */ private final long mask; /** * CRC result * CRC计算结果 */ private long crc; /** *

Constructor for CRCDigestAdapterImpl

*

CRC摘要算法适配器实现类类的构造方法

* * @param crcConfig CRC configure * CRC设置 */ public CRCDigestAdapterImpl(final CRCConfig crcConfig) { this.crcConfig = crcConfig; if (this.crcConfig.isRefIn()) { this.polynomial = reverseBit(this.crcConfig.getPolynomial(), this.crcConfig.getBit()); this.init = reverseBit(this.crcConfig.getInit(), this.crcConfig.getBit()); } else { this.polynomial = (this.crcConfig.getBit() < 8) ? (this.crcConfig.getPolynomial() << (8 - this.crcConfig.getBit())) : this.crcConfig.getPolynomial(); this.init = (this.crcConfig.getBit() < 8) ? (this.crcConfig.getInit() << (8 - this.crcConfig.getBit())) : this.crcConfig.getInit(); } this.crc = this.init; if (this.crcConfig.isRefIn()) { this.check = 0x1L; } else { if (this.crcConfig.getBit() <= 8) { this.check = 0x80; } else { this.check = Double.valueOf(Math.pow(2, this.crcConfig.getBit() - 1)).longValue(); } } if (this.crcConfig.getBit() <= 8) { this.mask = 0xFF; } else { StringBuilder stringBuilder = new StringBuilder(); while (stringBuilder.length() < this.crcConfig.getBit()) { stringBuilder.append("1"); } this.mask = Long.valueOf(stringBuilder.toString(), 2); } } /** *

Append parts of given binary data array to current adapter

*

追加给定的二进制字节数组到当前适配器

* * @param dataBytes binary data array * 二进制字节数组 * @param position Data begin position * 数据起始坐标 * @param length Length of data append * 追加的数据长度 * * @throws CryptoException * If an error occurs when process data * 当处理数据时出现异常 */ @Override public void append(final byte[] dataBytes, final int position, final int length) throws CryptoException { if (dataBytes.length < (position + length)) { throw new CryptoException(0x000000150001L, "Length_Not_Enough_Crypto_Error"); } for (int i = position ; i < length ; i++) { long crc = (dataBytes[i] < 0) ? ((int)dataBytes[i]) + 256 : dataBytes[i]; if (this.crcConfig.getBit() <= 8) { this.crc ^= crc; } else { this.crc ^= ((this.crcConfig.isRefIn() ? crc : (crc << (this.crcConfig.getBit() - 8))) & this.mask); } for (int j = 0; j < 8; j++) { if ((this.crc & this.check) > 0) { this.crc = (this.crcConfig.isRefIn() ? (this.crc >>> 1) : (this.crc << 1)) ^ this.polynomial; } else { this.crc = this.crcConfig.isRefIn() ? (this.crc >>> 1) : (this.crc << 1); } } } this.crc &= this.mask; } /** *

Append parts of given binary data array to current adapter and calculate final result

*

追加给定的二进制字节数组到当前适配器并计算最终结果

* * @param dataBytes binary data array * 二进制字节数组 * @param position Data begin position * 数据起始坐标 * @param length Length of data append * 追加的数据长度 * * @return Calculate result data byte array * 计算的二进制字节数组结果 * * @throws CryptoException * If an error occurs when process data * 当处理数据时出现异常 */ @Override public byte[] finish(final byte[] dataBytes, final int position, final int length) throws CryptoException { this.append(dataBytes, position, length); if (this.crcConfig.getBit() < 8 && !this.crcConfig.isRefIn()) { this.crc >>>= (8 - this.crcConfig.getBit()); } if (!Objects.equals(this.crcConfig.isRefIn(), this.crcConfig.isRefOut()) && this.crcConfig.isRefOut()) { // Just using for CRC-12/UMTS this.crc &= this.mask; this.crc = (reverseBit(this.crc, Long.toString(this.crc, 2).length()) ^ this.crcConfig.getXorOut()); } else { this.crc = (this.crc ^ this.crcConfig.getXorOut()) & this.mask; } byte[] result = new byte[8]; try { RawUtils.writeLong(result, ByteOrder.LITTLE_ENDIAN, this.crc); } catch (DataInvalidException ignore) { return new byte[0]; } this.reset(); return result; } /** *

Verify given signature data bytes is valid

*

验证给定的签名二进制数据是合法的

* * @param signature signature data bytes * 签名二进制数据 * * @return Verify result * 验证结果 */ @Override public boolean verify(final byte[] signature) { if (signature == null || signature.length != 8) { return Boolean.FALSE; } try { return this.crc == RawUtils.readLong(signature, ByteOrder.LITTLE_ENDIAN); } catch (DataInvalidException ignore) { return Boolean.FALSE; } } /** *

Reset current adapter

*

重置当前适配器

*/ @Override public void reset() { this.crc = this.init; } /** *

Reverse result bit

*

反转结果比特位

* * @param value result value * 结果值 * @param bit Bit value * 比特位 * * @return Reverse bit result * 反转比特位的结果值 */ private static long reverseBit(long value, int bit) { if (value < 0) { value += Math.pow(2, bit); } String reverseValue = new StringBuilder(Long.toString(value, 2)).reverse().toString(); if (reverseValue.length() < bit) { StringBuilder stringBuilder = new StringBuilder(reverseValue); while (stringBuilder.length() < bit) { stringBuilder.append("0"); } reverseValue = stringBuilder.toString(); } else { reverseValue = reverseValue.substring(0, bit); } return Long.parseLong(reverseValue, 2); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy