HarmonyOS 鸿蒙Next 这段 8位有符号整数转成string加rc4 java版代码在ets怎么写合适呢?

发布于 1周前 作者 wuwangju 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 这段 8位有符号整数转成string加rc4 java版代码在ets怎么写合适呢?

java版

主调用方法:

/**
 * @param data 需要解析的内容
 * @param key rc4的key
 */
public static String Rc4Decrypt(String data, String key) throws UnsupportedEncodingException {
    return HloveyRC4(new String(hexString2Bytes(data), "UTF-8"), key);
}

相关方法:

/**
 * 16进制字符串转字节数组
 *
 * @param src 16进制字符串
 * @return 字节数组
 */
public static byte[] hexString2Bytes(String src) {
    int l = src.length() / 2;
    byte[] ret = new byte[l];
    for (int i = 0; i < l; i++) {
        ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
    }
    return ret;
}
public static String HloveyRC4(String aInput, String aKey) {
    int[] iS = new int[256];
    byte[] iK = new byte[256];

    for (int i = 0; i < 256; i++)
        iS[i] = i;

    int j = 1;

    for (short i = 0; i < 256; i++) {
        iK[i] = (byte) aKey.charAt((i % aKey.length()));
    }

    j = 0;

    for (int i = 0; i < 255; i++) {
        j = (j + iS[i] + iK[i]) % 256;
        int temp = iS[i];
        iS[i] = iS[j];
        iS[j] = temp;
    }

    int i = 0;
    j = 0;
    char[] iInputChar = aInput.toCharArray();
    char[] iOutputChar = new char[iInputChar.length];
    for (int x = 0; x < iInputChar.length; x++) {
        i = (i + 1) % 256;
        j = (j + iS[i]) % 256;
        int temp = iS[i];
        iS[i] = iS[j];
        iS[j] = temp;
        int t = (iS[i] + (iS[j] % 256)) % 256;
        int iY = iS[t];
        char iCY = (char) iY;
        iOutputChar[x] = (char) (iInputChar[x] ^ iCY);
    }

    return new String(iOutputChar);
}

现在主要是卡在new String这里不知道怎么转了,因为hexString2Bytes这个方法不适用于Uint8Array,Uint8Array是无符号的。


更多关于HarmonyOS 鸿蒙Next 这段 8位有符号整数转成string加rc4 java版代码在ets怎么写合适呢?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

10 回复
DevEco Studio 3.1.1 Release

api 9  

真机打印结果

加密后的文本1(英文): c3b0641a1b3cc2b8c38f1579c2b93dc39fc290

加密后的文本2(中文): e591b0e59389e592bee596aa

解密后的文本1(英文): Hello, World!

解密后的文本2(中文): 哈哈哈嗝

解密后的文本: Hello, World!

解密后的文本: 哈哈哈哈哈哈哈

更多关于HarmonyOS 鸿蒙Next 这段 8位有符号整数转成string加rc4 java版代码在ets怎么写合适呢?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


执行结果
Encrypted Hex: 22a7f64b6f2c32766f726c6486
Decrypted Text: Hello, World!
是你要的效果不?注意,只能在真机上运行,预览器会失败

import util from '@ohos.util';

// 将文本转换为Uint8Array
function textToUint8Array(text: string): Uint8Array {
  let encodedText = new util.TextEncoder().encodeInto(text);
  return new Uint8Array(encodedText);
}

// 将Hex字符串转换为有符号8位整数数组
function hexString2Bytes(hexStr) {
  let bytes = [];
  for (let i = 0; i < hexStr.length; i += 2) {
    const signedByteValue = toSignedByte(hexStr.substr(i, 2));
    bytes.push(signedByteValue);
  }
  return new Int8Array(bytes);
}

// 将无符号16进制字符转换为有符号8位整数
function toSignedByte(hexString: string): number {
  const unsignedByte = parseInt(hexString, 16);
  const signedByte = ((unsignedByte << 24) >> 24);
  return signedByte;
}

// RC4加解密核心算法
function rc4Process(inputBytes: Uint8Array, key: string, encrypt: boolean) {
  let S = new Int8Array(256);
  let K = new Uint8Array(key.length);

  // 初始化S盒和密钥数组
  for (let i = 0; i < 256; i++) {
    S[i] = i;
  }
  for (let i = 0; i < K.length; i++) {
    K[i] = key.charCodeAt(i % key.length);
  }

  let j = 0;
  for (let i = 0; i < 256; i++) {
    j = (j + S[i] + K[i % K.length]) % 256;
    let temp = S[i];
    S[i] = S[j];
    S[j] = temp;
  }

  let i = 0;
  j = 0;
  let inputChars = Array.from(inputBytes);
  let outputBytes = new Uint8Array(inputBytes.length);

  for (let x = 0; x < inputChars.length; x++) {
    i = (i + 1) % 256;
    j = (j + S[i]) % 256;
    let temp = S[i];
    S[i] = S[j];
    S[j] = temp;
    let t = (S[i] + S[j] % 256) % 256;
    let Y = S[t];
    if (encrypt) {
      outputBytes[x] = inputChars[x] ^ Y;
    } else {
      outputBytes[x] = inputChars[x] ^ Y;
    }
  }

  return outputBytes;
}

// RC4加密方法
function rc4Encrypt(text: string, key: string): string {
  let inputBytes = textToUint8Array(text);
  let encryptedBytes = rc4Process(inputBytes, key, true);
  return Array.from(encryptedBytes).map(byte => byte.toString(16).padStart(2, '0')).join('');
}

// RC4解密方法
function rc4Decrypt(hexData: string, key: string): string {
  let inputBytes = hexString2Bytes(hexData);
  let decryptedBytes = rc4Process(new Uint8Array(inputBytes), key, false);
  let result = util.TextDecoder.create("utf-8").decodeWithStream(decryptedBytes);
  return result;
}

@Entry
@Component
struct test {
  build() {
    Column() {
      Button('测试').onClick(() => {
        // 示例数据
        const plaintext = 'Hello, World!';
        const key = 'Aa_12345678';

        // 加密并输出
        let encryptedHex = rc4Encrypt(plaintext, key);
        console.log('Encrypted Hex:', encryptedHex);

        // 解密并输出
        let decryptedText = rc4Decrypt(encryptedHex, key);
        console.log('Decrypted Text:', decryptedText);
      })
    }
  }
}

ConvertUtils2.hexString2Bytes(hexData);这段代码中,获取到的二进制有负数,跟java是一样的。

但是执行这段代码时就有问题了

let decryptedBytes = ConvertUtils2.rc4Process(new Uint8Array(inputBytes), key, false);

new Uint8Array(inputBytes)这个转成uint8Array就会全部变成正数,例如-62变成194,

上边的示例,我这边真机打印结果是这样的,你那边真机也是吗?

Encrypted Hex: 22a7f64b6f2c32766f726c6486
Decrypted Text: Hello, World!

只按照你这个示例是没问题的,但是用我们这边接口返回来的需要解码的文本,解码后就是乱码,java版解码就没问题,

再试试这个,我这边真机打印出来了

Decrypted Text: Hello, World!

// Java版的hexString2Bytes转换为TypeScript版
function hexString2Bytes(src: string): Uint8Array {
  const l = src.length / 2;
  const ret: number[] = new Array(l);
  for (let i = 0; i < l; i++) {
    ret[i] = parseInt(src.substr(i * 2, 2), 16);
  }
  return new Uint8Array(ret);
}

// 将Java版HloveyRC4转换为TypeScript版
function hloveyRC4(input: string, key: string): string {
  const s: number[] = new Array(256).fill(0);
  const k: [];

  for (let i = 0; i < 256; i++) {
    s[i] = i;
  }

  let j = 1;

  for (let i = 0; i < 256; i++) {
    k[i] = key.charCodeAt(i % key.length);
  }

  j = 0;

  for (let i = 0; i < 255; i++) {
    j = (j + s[i] + k[i]) % 256;
    const temp = s[i];
    s[i] = s[j];
    s[j] = temp;
  }

  let i = 0;
  j = 0;
  const inputCharCode = Array.from(input).map(c => c.charCodeAt(0));
  const outputCharCode: number[] = new Array(inputCharCode.length);

  for (let x = 0; x < inputCharCode.length; x++) {
    i = (i + 1) % 256;
    j = (j + s[i]) % 256;
    const temp = s[i];
    s[i] = s[j];
    s[j] = temp;
    const t = (s[i] + (s[j] % 256)) % 256;
    const y = s[t];
    outputCharCode[x] = inputCharCode[x] ^ y;
  }

  // 将解密后的字符码转换为字符串
  return util.TextDecoder.create("utf-8").decode(new Uint8Array(outputCharCode));
}

// 主调用方法
function rc4Decrypt(hexData: string, key: string): string {
  try {
    const decodedData = util.TextDecoder.create("utf-8").decode(hexString2Bytes(hexData));
    return hloveyRC4(decodedData, key);
  } catch (error) {
    throw new Error('Error during decryption');
  }
}

@Entry
@Component
struct Test {
  build() {
    Column() {
      Button('测试').onClick(() => {
        const data = 'C3B0641A1B3CC2B8C38F1579C2B93DC39FC290'; // 示例hex数据
        const key = 'Aa_12345678';

        const decryptedText = rc4Decrypt(data, key);
        console.log('Decrypted Text:', decryptedText);
      })
    }
  }
}

太谢谢了!可以!但是中文解析有乱码额。。

比如key是Aa_12345678
java版加密后是E591B0E59389E592BEE592BFE5929BE5919CE590A7

然后ets解密后是这个:�������

英文或者{}这种符号完全没问题

对了,请问ets的rc4加密的代码又是怎样的呢,

哈哈哈哈哈,

确实不支持中文,把java版的加解密源码发一下吧,要根据原版的java的加密逻辑来写解密逻辑。

// 假设Utils.jar已经包含在你的项目中,并且可以被ETS调用
import class Utils from 'Utils.jar'; // 伪代码,表示导入Java类

function convertAndEncrypt(intVal: number): string {
    // 假设Utils类中有一个static方法convertAndEncrypt
    // 注意:这里的语法是假设性的,实际语法需根据ETS支持的外部调用方式确定
    let result = Utils.convertAndEncrypt(intVal);
    return result;
}

// 调用示例
let intValue = -123; // 8位有符号整数示例
let encryptedString = convertAndEncrypt(intValue);
console.log(encryptedString);

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html,
回到顶部