2 questions about modbus function conversion and a socket library

Hello everybody!

I am new to this forum and I'm a very beginnger to swift.
I have to realize a simple, very simple application wich permit to calculate the CRC16 sum of a string (modbus).

I have both code from python and C++ to do that, but I don't know how to convert it for swift. I repeat it: I am new to swift, I'm learning it, but I need that code shortly.

C++ code:

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

string Crc16(const string& data, unsigned short bits=8)
{
    unsigned short crc = 0xFFFF;
    for (int i=0; i<data.size(); i+=2)
    {
        crc = crc ^ stoi(data.substr(i,2), nullptr, 16);
        for (int x=0; x<bits; ++x)
        {
            if (crc&0x0001 == 0x0001)
                crc =  (crc>>1) ^ 0xA001;
            else
                crc = crc >> 1;
        }
    }
    ostringstream oss;
    oss << uppercase << hex << (crc&0x00FF) << (crc>>8);
    return oss.str();
}

int main()
{
    cout << Crc16("11010003000C") << endl;
    return 0;
}

Python code:

def crc16(data, bits=8):
crc = 0xFFFF
for op, code in zip(data[0::2], data[1::2]):
    crc = crc ^ int(op+code, 16)
    for bit in range(0, bits):
        if (crc&0x0001)  == 0x0001:
            crc = ((crc >> 1) ^ 0xA001)
        else:
            crc = crc >> 1
msb = crc >> 8
lsb = crc & 0x00FF
return '{:X}{:X}'.format(lsb, msb)

print crc16('11010003000C')

Someone could help me to convert that for Swift 4?

And another question: with the latest 4.1 release, now Swift have a built in library for the socket communication?

Thanks a lot in advance!

It's as close a translation I could do against your python code.

func crc16(data: String, bits: Int = 8) -> String {
  var crc = 0xFFFF
  
  var opi = data.startIndex
  var codei = data.index(after: data.startIndex)
  let lasti = data.index(before: data.endIndex)
  
  while codei < data.endIndex {
    let op = data[opi]
    let code = data[codei]
    
    crc ^= Int(String(op) + String(code), radix: 16)!
    for _ in 0..<bits {
      if (crc & 0x0001) == 0x001 {
        crc = (crc >> 1) ^ 0xA001
      } else {
        crc = crc >> 1
      }
    }
    
    if let oi = data.index(opi, offsetBy: 2, limitedBy: lasti) {
      opi = oi
    } else {
      break
    }
    if let ci = data.index(codei, offsetBy: 2, limitedBy: lasti) {
      codei = ci
    } else {
      break
    }
  }
  let msb = String(format: "%X", crc >> 8)
  let lsb = String(format: "%X", crc & 0x00FF)
  return "\(lsb)\(msb)"
}
1 Like

You can actually more directly translate the Python example:

func crc16(data: String, bits: Int = 8) -> String {
  var crc = 0xFFFF
  
  let even = data.enumerated().filter({ $0.offset % 2 == 0 }).map({ $0.element })
  let odd = data.enumerated().filter({ $0.offset % 2 == 1 }).map({ $0.element })
  
  for (op, code) in zip(even, odd) {
    crc ^= Int(String(op) + String(code), radix: 16)!
    
    for _ in 0..<bits {
      if crc & 0x0001 == 0x0001 {
        crc = (crc >> 1) ^ 0xA001
      } else {
        crc >>= 1
      }
    }
  }
  
  let msb = crc >> 8
  let lsb = crc & 0x00FF
  
  return String(lsb, radix: 16) + String(msb, radix: 16)
}

print(crc16(data: "11010003000C"))
1 Like

Thanks a lot!!!!!!! You are my heroes!!!

Last question: with the latest 4.1 release, now Swift have a built in library for the socket communication?

Thanks again!!!!

Not really anything nice to use in the stdlib. There's always what you get with BSD sockets, but it doesn't have a nice Swift interface. But there's nice projects like Vapor's Engine that offers socket types. There's also NIO if you want to actually build a web framework.

1 Like

Ok, thanks for the explanation!!

Right now I think your best option for TCP networking is Foundation’s Stream type. It’s relatively Swift friendly — certainly a lot better than BSD Sockets — and avoids the need for an external dependency.

Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"
—
WWDC runs Mon, 4 Jun through to Fri, 8 Jun. During that time all
of DTS will be at the conference, helping folks out face-to-face.

2 Likes