// // KBSignUtils.m // keyBoard // // Created by Mac on 2025/12/4. // #import "KBSignUtils.h" #import @implementation KBSignUtils + (NSString *)urlEncode:(NSString *)value { if (!value) return @""; // 和 Swift 里的 .urlQueryAllowed 类似 NSCharacterSet *allowed = [NSCharacterSet URLQueryAllowedCharacterSet]; NSString *encoded = [value stringByAddingPercentEncodingWithAllowedCharacters:allowed]; return encoded ?: value; } + (NSString *)hmacSHA256:(NSString *)data secret:(NSString *)secret { const char *cKey = [secret cStringUsingEncoding:NSUTF8StringEncoding]; const char *cData = [data cStringUsingEncoding:NSUTF8StringEncoding]; unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC); // 转十六进制小写字符串 NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2]; for (int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) { [output appendFormat:@"%02x", cHMAC[i]]; } return output; } + (NSString *)signWithParams:(NSDictionary *)params secret:(NSString *)secret { // 1. 过滤空值 & sign 自身 NSMutableDictionary *filtered = [NSMutableDictionary dictionary]; [params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { if (!obj || obj.length == 0) return; if ([[key lowercaseString] isEqualToString:@"sign"]) return; filtered[key] = obj; }]; // 2. 按 key 字典序排序 NSArray *sortedKeys = [[filtered allKeys] sortedArrayUsingSelector:@selector(compare:)]; // 3. 拼接 key=value&key2=value2...&secret=xxx NSMutableArray *components = [NSMutableArray array]; for (NSString *key in sortedKeys) { NSString *value = filtered[key] ?: @""; NSString *encodedValue = [self urlEncode:value]; NSString *part = [NSString stringWithFormat:@"%@=%@", key, encodedValue]; [components addObject:part]; } NSString *encodedSecret = [self urlEncode:secret]; NSString *secretPart = [NSString stringWithFormat:@"secret=%@", encodedSecret]; [components addObject:secretPart]; NSString *dataString = [components componentsJoinedByString:@"&"]; // 4. HMAC-SHA256 NSString *sign = [self hmacSHA256:dataString secret:secret]; return sign; } + (NSString *)currentTimestamp { NSTimeInterval ts = [[NSDate date] timeIntervalSince1970]; long long seconds = (long long)ts; return [NSString stringWithFormat:@"%lld", seconds]; } + (NSString *)generateNonceWithLength:(NSUInteger)length { // 用 UUID 生成,去掉 - , 再截取前 length 位 NSString *uuid = [[NSUUID UUID].UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""]; if (length == 0 || length > uuid.length) { return uuid; } return [uuid substringToIndex:length]; } @end