From 2bff3cf6cc09291461ff29ea74f606d7b6524512 Mon Sep 17 00:00:00 2001 From: ila Date: Mon, 6 Jul 2026 21:52:48 +0800 Subject: [PATCH] =?UTF-8?q?feat(osi):=20=E5=AE=9E=E7=8E=B0=20MD5=20?= =?UTF-8?q?=E5=A4=B4=E7=AD=BE=E5=90=8D=E4=B8=8E=E8=AF=B7=E6=B1=82=E5=A4=B4?= =?UTF-8?q?=E7=BB=84=E8=A3=85=EF=BC=88T-002=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit password=md5("ts=&ask=") 32 位小写;ask 仅参与签名不进 headers 测试向量与本地 Python 联调脚本对齐 Co-Authored-By: Claude Opus 4.8 --- osi/sign.go | 30 ++++++++++++++++++++++++++++++ osi/sign_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 osi/sign.go create mode 100644 osi/sign_test.go diff --git a/osi/sign.go b/osi/sign.go new file mode 100644 index 0000000..c89a0da --- /dev/null +++ b/osi/sign.go @@ -0,0 +1,30 @@ +package osi + +import ( + "crypto/md5" + "encoding/hex" +) + +type HeaderInput struct { + OrgCode string + DeviceSN string + UserName string + Ask string + TS string +} + +func SignPassword(ts, ask string) string { + sum := md5.Sum([]byte("ts=" + ts + "&ask=" + ask)) + return hex.EncodeToString(sum[:]) +} + +func BuildHeaders(input HeaderInput) map[string]string { + return map[string]string{ + "Content-Type": "application/json", + "orgCode": input.OrgCode, + "deviceSN": input.DeviceSN, + "ts": input.TS, + "userName": input.UserName, + "password": SignPassword(input.TS, input.Ask), + } +} diff --git a/osi/sign_test.go b/osi/sign_test.go new file mode 100644 index 0000000..6e1f027 --- /dev/null +++ b/osi/sign_test.go @@ -0,0 +1,43 @@ +package osi + +import "testing" + +func TestSignPasswordMatchesPythonScriptVector(t *testing.T) { + got := SignPassword("1700000000123", "secret-key") + want := "008aceff8247cb42d2a99b2c48d0ac88" + if got != want { + t.Fatalf("SignPassword() = %q, want %q", got, want) + } +} + +func TestBuildHeadersIncludesSignatureFields(t *testing.T) { + headers := BuildHeaders(HeaderInput{ + OrgCode: "12441625456962881G", + DeviceSN: "device-001", + UserName: "dyytgw", + Ask: "secret-key", + TS: "1700000000123", + }) + + if headers["Content-Type"] != "application/json" { + t.Fatalf("Content-Type = %q", headers["Content-Type"]) + } + if headers["orgCode"] != "12441625456962881G" { + t.Fatalf("orgCode = %q", headers["orgCode"]) + } + if headers["deviceSN"] != "device-001" { + t.Fatalf("deviceSN = %q", headers["deviceSN"]) + } + if headers["ts"] != "1700000000123" { + t.Fatalf("ts = %q", headers["ts"]) + } + if headers["userName"] != "dyytgw" { + t.Fatalf("userName = %q", headers["userName"]) + } + if headers["password"] != "008aceff8247cb42d2a99b2c48d0ac88" { + t.Fatalf("password = %q", headers["password"]) + } + if _, ok := headers["ask"]; ok { + t.Fatal("headers must not include ask") + } +}