golang验证RFC 4122标准UUID并转换UUIDv7为UTC时间戳插件库uuidcheck的使用

Golang验证RFC 4122标准UUID并转换UUIDv7为UTC时间戳插件库uuidcheck的使用

简介

uuidcheck是一个轻量级、零依赖的Go库,用于验证UUID是否符合RFC 4122标准格式,并能将UUIDv7转换为时间戳。它设计简单高效,专注于单一功能。

特性

  • 简单轻量:不使用正则表达式,没有外部依赖,单次检查
  • 严格RFC 4122格式验证:确保正确的长度、连字符位置和有效的十六进制字符
  • UUIDv7支持:从版本7的UUID中提取嵌入的时间戳
  • 全面测试:包含覆盖各种边缘情况的单元测试

安装

go get github.com/ashwingopalsamy/uuidcheck

工作原理

  • IsValidUUID执行以下检查:

    • 长度检查:必须正好36个字符
    • 连字符位置:连字符必须出现在第8、13、18和23位
    • 十六进制数字:其他字符必须是有效的十六进制数字(0-9,A-F,a-f)
  • IsUUIDv7检查time_hi_and_version字段的版本号,确保是’7’

  • UUIDv7ToTimestamp从UUID中提取前48位(time_low和部分time_mid的组合),并将其解释为Unix时间戳(毫秒)

使用示例

验证UUID

package main

import (
	"fmt"
	"github.com/ashwingopalsamy/uuidcheck"
)

func main() {
	// 有效的UUID示例
	validUUID := "01939c00-282d-782f-9cc2-887dc7b40629"
	
	// 验证UUID是否符合RFC 4122标准
	if uuidcheck.IsValidUUID(validUUID) {
		fmt.Println("UUID是有效的")
	} else {
		fmt.Println("UUID无效")
	}
	
	// 检查是否是UUIDv7
	if uuidcheck.IsUUIDv7(validUUID) {
		fmt.Println("这是一个UUIDv7")
	} else {
		fmt.Println("这不是UUIDv7")
	}
}

转换UUIDv7为时间戳

package main

import (
	"fmt"
	"time"
	"github.com/ashwingopalsamy/uuidcheck"
)

func main() {
	// UUIDv7示例
	uuidv7 := "018f0a24-1dd2-7f3b-8000-7a806fc1e8eb"
	
	// 检查是否是UUIDv7
	if uuidcheck.IsUUIDv7(uuidv7) {
		// 转换为时间戳(毫秒)
		timestamp := uuidcheck.UUIDv7ToTimestamp(uuidv7)
		
		// 转换为time.Time
		t := time.Unix(0, timestamp*int64(time.Millisecond))
		fmt.Println("UUIDv7对应的时间:", t.UTC())
	} else {
		fmt.Println("提供的UUID不是v7版本")
	}
}

综合示例

package main

import (
	"fmt"
	"time"
	"github.com/ashwingopalsamy/uuidcheck"
)

func main() {
	// 测试用例
	testUUIDs := []string{
		"01939c00-282d-782f-9cc2-887dc7b40629", // 有效UUIDv7
		"f47ac10b-58cc-4372-a567-0e02b2c3d479", // 有效UUIDv4
		"01939c-282d-782f-9cc2-887",             // 太短
		"f01939c00-282d-782f-9cg2-887dc7b40629", // 无效十六进制字符
		"01939c00282d782f9cc2887dc7b40629",      // 无连字符
	}

	for _, uuid := range testUUIDs {
		fmt.Printf("测试UUID: %s\n", uuid)
		
		// 验证UUID
		if !uuidcheck.IsValidUUID(uuid) {
			fmt.Println("  → 无效的UUID格式")
			continue
		}
		
		fmt.Println("  → 有效的UUID格式")
		
		// 检查版本
		if uuidcheck.IsUUIDv7(uuid) {
			timestamp := uuidcheck.UUIDv7ToTimestamp(uuid)
			t := time.Unix(0, timestamp*int64(time.Millisecond))
			fmt.Printf("  → 这是UUIDv7,时间戳: %d (UTC: %v)\n", timestamp, t.UTC())
		} else {
			fmt.Println("  → 这不是UUIDv7")
		}
	}
}

测试

项目包含全面的测试用例,可以运行以下命令执行测试:

go test -v ./...

贡献

欢迎贡献代码!可以提交issue或PR,保持代码简单高效,符合库的目标。

许可证

本项目采用MIT许可证。


更多关于golang验证RFC 4122标准UUID并转换UUIDv7为UTC时间戳插件库uuidcheck的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang验证RFC 4122标准UUID并转换UUIDv7为UTC时间戳插件库uuidcheck的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang UUID验证与UUIDv7时间戳转换

RFC 4122 UUID验证

在Go中验证UUID是否符合RFC 4122标准,可以使用标准库或第三方库。以下是几种方法:

使用标准库

package main

import (
	"fmt"
	"regexp"
)

func IsValidUUID(uuid string) bool {
	r := regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
	return r.MatchString(uuid)
}

func main() {
	uuid := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
	fmt.Println(IsValidUUID(uuid)) // true
}

使用github.com/google/uuid库

package main

import (
	"fmt"
	"github.com/google/uuid"
)

func main() {
	uuidStr := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
	_, err := uuid.Parse(uuidStr)
	if err != nil {
		fmt.Println("无效的UUID:", err)
	} else {
		fmt.Println("有效的UUID")
	}
}

UUIDv7时间戳转换

UUIDv7包含时间戳信息,可以使用专门的库来提取时间信息。以下是使用uuidcheck库的示例:

安装uuidcheck

go get github.com/uuidcheck/uuidcheck

使用示例

package main

import (
	"fmt"
	"time"
	
	"github.com/uuidcheck/uuidcheck"
)

func main() {
	// 示例UUIDv7 (假设这是一个有效的UUIDv7)
	uuidStr := "017f22e2-79b0-7cc3-98c4-dc0c0c07398f"
	
	// 验证UUID并提取时间戳
	uuidInfo, err := uuidcheck.Parse(uuidStr)
	if err != nil {
		fmt.Printf("UUID解析错误: %v\n", err)
		return
	}
	
	// 检查是否为UUIDv7
	if uuidInfo.Version() != 7 {
		fmt.Println("这不是一个UUIDv7")
		return
	}
	
	// 获取时间戳
	timestamp := uuidInfo.Timestamp()
	
	// 转换为UTC时间
	utcTime := time.Unix(int64(timestamp/1000), 0).UTC()
	
	fmt.Printf("UUID: %s\n", uuidStr)
	fmt.Printf("版本: %d\n", uuidInfo.Version())
	fmt.Printf("时间戳(毫秒): %d\n", timestamp)
	fmt.Printf("UTC时间: %s\n", utcTime.Format(time.RFC3339))
	
	// 也可以直接获取时间
	if uuidInfo.HasTime() {
		utcTime := uuidInfo.Time().UTC()
		fmt.Printf("直接获取的UTC时间: %s\n", utcTime.Format(time.RFC3339))
	}
}

注意事项

  1. UUIDv7是2021年提出的新UUID版本,不是所有库都支持
  2. uuidcheck库需要确认其是否支持UUIDv7,如果不行,可以考虑其他专门处理UUIDv7的库
  3. 对于生产环境,建议使用成熟的UUID库如github.com/google/uuid

替代方案

如果没有找到合适的uuidcheck实现,可以手动解析UUIDv7的时间戳:

package main

import (
	"encoding/binary"
	"fmt"
	"time"
)

func ExtractUUIDv7Timestamp(uuidStr string) (uint64, error) {
	// 移除连字符
	uuidBytes := []byte(uuidStr)
	if len(uuidBytes) != 36 {
		return 0, fmt.Errorf("invalid UUID length")
	}
	
	// 转换为字节数组
	var uuid [16]byte
	_, err := fmt.Sscanf(uuidStr, "%8x-%4x-%4x-%4x-%12x",
		&uuid[0:4],
		&uuid[4:6],
		&uuid[6:8],
		&uuid[8:10],
		&uuid[10:16])
	if err != nil {
		return 0, err
	}
	
	// 检查版本号(第7字节的高4位)
	version := uuid[6] >> 4
	if version != 7 {
		return 0, fmt.Errorf("not a UUIDv7")
	}
	
	// 提取时间戳(前48位)
	timestampBytes := append([]byte{0, 0}, uuid[0:6]...)
	timestamp := binary.BigEndian.Uint64(timestampBytes)
	
	return timestamp, nil
}

func main() {
	uuidStr := "017f22e2-79b0-7cc3-98c4-dc0c0c07398f"
	timestamp, err := ExtractUUIDv7Timestamp(uuidStr)
	if err != nil {
		fmt.Println("错误:", err)
		return
	}
	
	// 转换为UTC时间(Unix时间戳,毫秒)
	utcTime := time.Unix(int64(timestamp/1000), 0).UTC()
	fmt.Printf("时间戳: %d\n", timestamp)
	fmt.Printf("UTC时间: %s\n", utcTime.Format(time.RFC3339))
}

以上代码提供了多种方法来验证UUID和提取UUIDv7中的时间戳信息。根据您的具体需求选择合适的实现方式。

回到顶部