没有高级数据类型的字符串到int到字节数组

问题描述 投票:0回答:2

这可能是一个困难的问题,但我正在尝试执行以下操作:

取一个输入字符串i,我希望它是一个包含毫秒的unix时间戳 将其转换为 int64 字节数组,但我只能使用更简单的结构进行操作,我最大的可用 int 是 32 位,扩展一点这是用于 PLC 向数据库发送一些电报

Wanted input:
  "1707461225120" // int64 string 
Should return:
  [00, 00, 01, 8D, 8C, 9E, AA, A0] // 8 byte array

我并不关心用什么语言来回答,我只关心解决这个问题的逻辑思维,任何东西都会有帮助,没有高级数据类型

我尝试了以下操作(想要将字符串转换为 int64 8 字节数组),很抱歉,如果这是一种奇怪的语言,但它是我所拥有的,对于响应,我不需要相同的格式,我只需要一般逻辑/数学,没有高级数据类型

    byArray : Array[0..31] OF Byte; // temp array of characters in string
    byArrayO : Array[0..7] OF Byte; // temp memory before converting to output
    charCount : Int; // temp amount of characters in input string 16 bit int
    il : Int; // temp counter generic 16 bit int
    i : String; // input string
    o : Array[0..7] OF Byte; // output byte array

    // reset temp memory
    FOR #il := 0 TO 7 DO
        #o[#il] := 0;
        #byArrayO[#il] := 0;
    END_FOR;

    // Convert string to character array
    "STRING_TO_CHARS"(Chars => #byArray,
                      Cnt => #charCount,
                      pChars := 0,
                      Strg := #i); 
    
    // loop character array, here's what im doing wrong, but unsure how to solve this
    FOR #il := 0 TO #charCount - 2 DO // - 2 due to character count offset by 2
        // Function adds an int to a byte array
        "ADD_BYTE_ARRAY"(iAdd := (#byArray[#il] - 48) * 10 ** #il, // convert int char to int and offset
                        arr := #byArrayO); // array to add to
    END_FOR;
    
    #o := #byArrayO;

通过这篇文章https://stackoverflow.com/a/28201576/23369035我需要调整 add_byte_Array 输入以保留旧 val 值的内存,但是当我无法使用时,如何使用字节数组来完成此操作int64?

Wanted input:
  "1707461225120"
Should return:
  [00, 00, 01, 8D, 8C, 9E, AA, A0]
What my code does:
   adds the characters in the string together one by one :/
arrays logic byte plc bytebuffer
2个回答
0
投票

我通过将字节数组乘以 int32 值然后加上毫秒来“解决”了我的问题

MULT_BYTE_ARRAY

// Multiply to byte array and carry over

#carry := 0;
FOR #i := #LEN TO 0 BY -1 DO
    #sum := BYTE_TO_UDINT(#arr[#i]) * #iMult + #carry;
    #carry := SHR(IN := #sum, N := 8);
    #arr[#i] := UDINT_TO_BYTE(#sum);
END_FOR;
ADD_BYTE_ARRAY

// Add to byte array and carry over

#carry := #iAdd;
FOR #i := #LEN TO 0 BY -1 DO
    #sum := (#arr[#i] & 255) + #carry;
    #arr[#i] := UDINT_TO_BYTE(#sum);
    #carry := SHR(IN := #sum, N := 8);
END_FOR;
"ADD_BYTE_ARRAY"(iAdd := STRING_TO_UDINT(#i), // regular unix timestamp in
                 arr := #byArrayO); 

"MULT_BYTE_ARRAY"(iMult := 1000,
                  arr := #byArrayO);

在此之后,我可以使用 ADD_BYTE_ARRAY 添加 ms,当你知道不会有任何溢出时,效果很好


0
投票

此外,您还可以使用 add 和 mumlt 字节数组来制作 int64_str_to_bytes

FUNCTION "LINT_STR_TO_BYTES" : Void

VAR_INPUT
  s : String;
END_VAR

VAR_OUTPUT
  bytes : Array[0..#INT64_LEN] OF Byte;
END_VAR

VAR_IN_OUT

END_VAR

VAR_TEMP
  c : Int; // count
  bytesTemp : Array[0..#INT64_LEN] OF Byte;
  strLen : Int;
END_VAR

VAR CONSTANT
  INT64_LEN : Int := 7; // 8 bytes in lint
END_VAR

FOR #c := 0 TO #INT64_LEN DO // clear temp
    #bytesTemp[#c] := 0;
END_FOR;

#strLen := LEN(#s);

FOR #c := 1 TO #strLen DO
    "ADD_BYTE_ARRAY"(arr := #bytesTemp,
                     iAdd := CHAR_TO_BYTE(#s[#c]) - 48);
    IF (#c <> #strLen) THEN
        "MULT_BYTE_ARRAY"(arr := #bytesTemp,
                          iMult := 10);
    END_IF;
END_FOR;

#bytes := #bytesTemp;
© www.soinside.com 2019 - 2024. All rights reserved.