| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- const {
- CRC_ALGORITHM_PRESETS,
- calculateCrc
- } = require('../../utils/crc.js')
- const {
- HASH_ALGORITHM_PRESETS,
- calculateHash
- } = require('./hash.js')
- const {
- formatBytes,
- stringToUtf8Bytes
- } = require('../../utils/binary-utils.js')
- const INPUT_TYPE_OPTIONS = [
- { key: 'hex', label: 'HEX' },
- { key: 'string', label: 'String' },
- { key: 'base64', label: 'Base64' }
- ]
- const ALGORITHM_PRESETS = CRC_ALGORITHM_PRESETS
- .map((preset) => ({ ...preset, kind: 'crc' }))
- .concat(HASH_ALGORITHM_PRESETS)
- const CRC_CONFIG_FIELDS = [
- 'crcInitialValue',
- 'crcPoly',
- 'crcWidth',
- 'crcXorOut'
- ]
- function clonePreset(preset) {
- return {
- ...preset
- }
- }
- function getPreset(index) {
- return clonePreset(ALGORITHM_PRESETS[Number(index)] || ALGORITHM_PRESETS[0])
- }
- function getCustomPresetIndex() {
- return Math.max(0, ALGORITHM_PRESETS.findIndex((preset) => preset.custom))
- }
- function getInputType(index) {
- return INPUT_TYPE_OPTIONS[Number(index)] || INPUT_TYPE_OPTIONS[0]
- }
- function createPresetState(presetIndex = 0) {
- const preset = getPreset(presetIndex)
- const kind = preset.kind || 'crc'
- return {
- crcAlgorithmCollapsed: !(preset.custom || kind === 'hmac' || kind === 'pbkdf2'),
- crcAlgorithmKind: kind,
- crcInitialValue: preset.init || 'FFFF',
- crcPoly: preset.poly || '1021',
- crcPresetIndex: Number(presetIndex),
- crcReflectIn: !!preset.reflectIn,
- crcReflectOut: !!preset.reflectOut,
- crcShowBinResult: kind === 'crc',
- crcShowCrcConfig: kind === 'crc',
- crcShowHmacKey: kind === 'hmac',
- crcShowPbkdf2Config: kind === 'pbkdf2',
- crcWidth: String(preset.width || 16),
- crcXorOut: preset.xorOut || '0000'
- }
- }
- function createInitialState() {
- return {
- ...createPresetState(0),
- crcDataLengthText: '0 bytes',
- crcDataText: '',
- crcErrorText: '',
- crcFileName: '',
- crcFileSizeText: '',
- crcHmacKey: '',
- crcInputTypeIndex: 0,
- crcInputTypeOptions: INPUT_TYPE_OPTIONS,
- crcPbkdf2Iterations: '1000',
- crcPbkdf2Length: '32',
- crcPbkdf2Salt: '',
- crcPresetOptions: ALGORITHM_PRESETS.map(clonePreset),
- crcResultBase64: '--',
- crcResultBin: '--',
- crcResultBinLines: splitBinaryResult('--'),
- crcResultHex: '--'
- }
- }
- function normalizeHexData(text) {
- return String(text || '')
- .replace(/0x/gi, '')
- .replace(/[\s,_:-]/g, '')
- }
- function parseHexBytes(text) {
- const hexText = normalizeHexData(text)
- if (!hexText) return []
- if (!/^[0-9A-F]+$/i.test(hexText)) throw new Error('HEX 数据包含非法字符')
- if (hexText.length % 2 !== 0) throw new Error('HEX 数据长度必须为偶数字符')
- const bytes = []
- for (let index = 0; index < hexText.length; index += 2) {
- bytes.push(parseInt(hexText.slice(index, index + 2), 16))
- }
- return bytes
- }
- function parseBase64Bytes(text) {
- const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
- let normalized = String(text || '').replace(/\s/g, '')
- if (!normalized) return []
- if (normalized.length % 4 === 1 || /[^A-Za-z0-9+/=]/.test(normalized)) {
- throw new Error('Base64 数据无效')
- }
- while (normalized.length % 4 !== 0) {
- normalized += '='
- }
- const bytes = []
- for (let index = 0; index < normalized.length; index += 4) {
- const chars = normalized.slice(index, index + 4)
- const values = chars.split('').map((char) => (char === '=' ? 0 : alphabet.indexOf(char)))
- if (values.some((value) => value < 0)) throw new Error('Base64 数据无效')
- const triple = (values[0] << 18) | (values[1] << 12) | (values[2] << 6) | values[3]
- bytes.push((triple >> 16) & 0xFF)
- if (chars[2] !== '=') bytes.push((triple >> 8) & 0xFF)
- if (chars[3] !== '=') bytes.push(triple & 0xFF)
- }
- return bytes
- }
- function parseInputBytes(dataText, inputTypeIndex) {
- const inputType = getInputType(inputTypeIndex)
- if (inputType.key === 'hex') return parseHexBytes(dataText)
- if (inputType.key === 'base64') return parseBase64Bytes(dataText)
- return stringToUtf8Bytes(dataText)
- }
- function splitBinaryResult(value) {
- const text = String(value || '--')
- if (text === '--' || text.length <= 32) return [
- {
- id: 'bin-line-0',
- text
- }
- ]
- const lineLength = Math.ceil(text.length / 2)
- return [
- {
- id: 'bin-line-0',
- text: text.slice(0, lineLength)
- },
- {
- id: 'bin-line-1',
- text: text.slice(lineLength)
- }
- ]
- }
- function getConfigFromState(state) {
- const preset = (state.crcPresetOptions || [])[Number(state.crcPresetIndex)] || {}
- return {
- init: state.crcInitialValue,
- key: preset.key || '',
- poly: state.crcPoly,
- reflectIn: !!state.crcReflectIn,
- reflectOut: !!state.crcReflectOut,
- useLookupTable: !!preset.key && !preset.custom,
- width: state.crcWidth,
- xorOut: state.crcXorOut
- }
- }
- function getHashConfigFromState(state) {
- const preset = (state.crcPresetOptions || [])[Number(state.crcPresetIndex)] || {}
- return {
- hmacKey: state.crcHmacKey,
- key: preset.key || '',
- pbkdf2Iterations: state.crcPbkdf2Iterations,
- pbkdf2Length: state.crcPbkdf2Length,
- pbkdf2Salt: state.crcPbkdf2Salt
- }
- }
- function calculateFromState(state, fileBytes) {
- const bytes = fileBytes
- ? Array.prototype.slice.call(fileBytes)
- : parseInputBytes(state.crcDataText, state.crcInputTypeIndex)
- const preset = (state.crcPresetOptions || [])[Number(state.crcPresetIndex)] || {}
- const result = (preset.kind || 'crc') === 'crc'
- ? calculateCrc(bytes, getConfigFromState(state))
- : calculateHash(bytes, getHashConfigFromState(state))
- return {
- crcDataLengthText: formatBytes(bytes.length),
- crcErrorText: '',
- crcResultBase64: result.base64,
- crcResultBin: result.bin,
- crcResultBinLines: splitBinaryResult(result.bin),
- crcResultHex: result.hex
- }
- }
- module.exports = {
- calculateFromState,
- createInitialState,
- createPresetState,
- CRC_CONFIG_FIELDS,
- getCustomPresetIndex
- }
|