0

我正在尝试以DateTime以下格式将当前连接到我的设备 Mac 地址:aa:bb:cc:dd:ee:ffYYmmDDhhMMss所以我可以在每次收集新数据时对其进行哈希处理并将其发送到 Web 服务(因此我必须在每个循环中对其进行哈希处理)

我设法连接两个值(mac地址+日期时间)并将其转换为char数组

addressDateTime.toCharArray(thisThing, 28);

但是,对于如何继续,我有点迷茫。

我也尝试阅读char*这个循环的结果,但我不明白为什么它不起作用:

void loop() {
  while (!timeClient.update()) {
    timeClient.forceUpdate();
  }
  String addressDateTime = getPayload(); //this gets the *aa:bb:cc:dd:ee:ffYYmmDDhhMMss* string
  char* hashThis;
  addressDateTime.toCharArray(hashThis, 28);

  for (int i = 0; i < sizeof(hashThis); i++) {
    char str[3];
    sprintf(str, "%02x", hashThis[i]);
    Serial.print(str);
  }
  delay(5000);
}

我是否正确转换Stringchar*

我应该如何去散列char*

或者我可以散列字符串而不将其转换为char*

更新:

我的代码看起来像这样

  while (!timeClient.update()) {
    timeClient.forceUpdate();
  }
  String addressDateTime = getPayload();
  char hashThis[30];
  addressDateTime.toCharArray(hashThis, 30);

  for (int i = 0; i < sizeof(hashThis); i++) {
    Serial.printf("%02x", hashThis[i]);
  }
  delay(5000);
}

所以我设法将其转换StringChar*除了输出看起来像这样33433a37313a42463a31443a34323a463431393035303531343038323700而不是(例如)aa:bb:cc:dd:ee:ff190505141037

在弄清楚为什么我的char*数组输出像这样之后,我仍然需要对其进行哈希处理。

感谢您帮助我走到这一步,我还有很长的路要走

4

1 回答 1

1

您没有分配空间来存储您从中获取的 C 字符串addressDateTime

hashThischar*一个指向字符的指针。它没有被设置为任何东西,所以它只是......随机的。这几乎肯定会使您的程序崩溃或至少行为不端。

给定您的代码,最快的解决方法是更改

    char* hashThis;

    char hasThis[30];
    addressDateTime.toCharArray(hashThis, 30);

我将 28 更改为 30 因为aa:bb:cc:dd:ee:ffYYmmDDhhMMss实际上是 29 个字符长,并且还需要一个额外的字节用于 C 字符串空终止符字符。我不是 100% 确定该toCharArray()方法是否设置了空终止符;如果没有,您需要添加

    hasThis[29] = '\0';

您可以通过使用 Stringc_str()方法来避免这种情况,该方法将 a 返回char*到 String 用来保存字符串的内部缓冲区。

在这种情况下,您可以重写

    char* hashThis;
    addressDateTime.toCharArray(hashThis, 28);

作为

    char* hashThis = addressDateTime.c_str();

顺便说一句,你也可以这样做

    Serial.printf("%02x", hashThis[i]);

并省去snprintf(). 不过,很高兴在那里获得正确的缓冲区大小!

更新

在您更新的问题中,您说您希望看到如下所示的输出:

aa:bb:cc:dd:ee:ff190505141037

代替:

33433a37313a42463a31443a34323a463431393035303531343038323700

你的代码是

for (int i = 0; i < sizeof(hashThis); i++) {
  Serial.printf("%02x", hashThis[i]);
}

您将每个字符写为两位十六进制数字,因此您将看到代表字符的十六进制数字,而不是字符本身。如果要查看字符,请执行以下操作:

for (int i = 0; i < strlen(hashThis); i++) {
  Serial.printf("%c", hashThis[i]);
}

或更好)

for (int i = 0; i < strlen(hashThis); i++) {
  Serial.print(hashThis[i]);
}

或(最好)

Serial.println(hashThis);

请注意,我将您的更改sizeofstrlen. 如果由于某种原因您在 , 中放入了较短的字符串hashThisstrlen则会做正确的事情,而sizeof将始终返回hashThis声明的长度,而不是其中字符串的长度。

于 2019-05-05T00:29:14.003 回答