元始天尊 发表于 2021-8-4 21:41:55

越狱开发初级之UUID

本帖最后由 元始天尊 于 2021-8-4 21:45 编辑



## 什么是UUID

&emsp;&emsp;UUID即Unique Device Identifier,唯一设备识别符。iOS上的IDFA/IDFV/OpenUDID/macho-uuid,都采用UUID4格式。UUID是RFC定义的高随机性的标识字符串,结构说明在<https://www.ietf.org/rfc/rfc4122.txt>

```
struct rfc_uuid {
    uint32_ttime_low;
    uint16_ttime_mid;
    uint16_ttime_hi_and_version;          // v=(v&0xfff)|0x400
    uint8_t   clock_seq_hi_and_reserved;    // v=(v&0x3f)|0x80
    uint8_t   clock_seq_low;
    uint8_t   node;
};
```

&emsp;&emsp;UUID目前有多个版本,包括UUID1/UUID3/UUID4/UUID5,一个典型的UUID4串`ef9cbf1e-3560-4555-b1aa-81bf4773cd9e`。注意uuid4的结构和其他类型不同,有些bit位固定为0或1,其他bit位完全随机(`********-****-4***-(8|9|a|b)***-************`),因此如果用上面的结构体解析UUID4串是没有意义的。正如rfc所述:

```
4.4.Algorithms for Creating a UUID from Truly Random or
      Pseudo-Random Numbers
   The version 4 UUID is meant for generating UUIDs from truly-random or
   pseudo-random numbers.
   The algorithm is as follows:
   oSet the two most significant bits (bits 6 and 7) of the
      clock_seq_hi_and_reserved to zero and one, respectively.
   oSet the four most significant bits (bits 12 through 15) of the
      time_hi_and_version field to the 4-bit version number from
      Section 4.1.3.
   oSet all the other bits to randomly (or pseudo-randomly) chosen
      values.
```

&emsp;&emsp;使用ObjC和Python生成uuid4

```
// Objective-C生成UUID
NSString* myuuid = NSUUID.UUID.UUIDString;
// Python生成UUID
import uuid
myuuid = str(uuid.uuid4())
```

&emsp;&emsp;讲一个趣事,之前一个朋友不知道IDFA用UUID4格式生成,用Hook修改系统IDFA获取的部分,改为纯随机,结果跑起来莫名其妙就是崩。。。。改机软件模拟的UUID均为上述方式生成。

## 怎样生成相对固定的uuid4

&emsp;&emsp;此需求看似有点奇怪,但是其实是有用的。在模拟参数的时候如果uuid需要和其他参数配套,那么固定一个参数去生成uuid就十分必要了。这里提供一个使用时间戳生成uuid4的实例

```
void uuid4_format(unsigned char* buf) { // bufsize=16
    struct rfc_uuid* uuid = (struct rfc_uuid*)buf;
    uuid->time_hi_and_version = (uuid->time_hi_and_version & 0xff0f) | 0x0040;
    uuid->clock_seq_hi_and_reserved = (uuid->clock_seq_hi_and_reserved & 0x3f) | 0x80;
}

NSString* uuid4_init_with_ts(time_t ts) {
    unsigned char uuid;
    if (ts == 0) {
      ts = time(0);
    }
    ((uint32_t*)uuid) = crc32_for_byte(ts & 0xff);
    ((uint32_t*)uuid) = crc32_for_byte((ts >> 8) & 0xff);
    ((uint32_t*)uuid) = crc32_for_byte((ts >> 16) & 0xff);
    ((uint32_t*)uuid) = crc32_for_byte((ts >> 24) & 0xff);
    uuid4_format(uuid);
    NSUUID* nsuuid = [ initWithUUIDBytes:uuid];
    return nsuuid.UUIDString;
}
```


页: [1]
查看完整版本: 越狱开发初级之UUID