device_no
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m22s

This commit is contained in:
shanshanzhong 2026-03-18 10:28:55 -07:00
parent 1e12c58986
commit de6fbcb518
5 changed files with 61 additions and 12 deletions

View File

@ -90,7 +90,7 @@ type RegisterConfig struct {
IpRegisterLimit int64 `yaml:"IpRegisterLimit" default:"0"`
IpRegisterLimitDuration int64 `yaml:"IpRegisterLimitDuration" default:"0"`
EnableIpRegisterLimit bool `yaml:"EnableIpRegisterLimit" default:"false"`
DeviceLimit int64 `yaml:"DeviceLimit" default:"5"`
DeviceLimit int64 `yaml:"DeviceLimit" default:"2"`
}
type EmailConfig struct {

View File

@ -5,13 +5,47 @@ import (
"strings"
)
const deviceHashSalt uint32 = 0x5A3C7E9B
// 乘法逆元参数mod 2^32
// multiplier 必须是奇数,与 2^32 互质
// inverse 满足: multiplier * inverse ≡ 1 (mod 2^32)
const (
deviceMultiplier uint32 = 0x45D9F3B7 // 奇数乘数
deviceInverse uint32 = 0x9B845A07 // 乘法逆元 (multiplier * inverse = 1 mod 2^32)
deviceXorKey1 uint32 = 0x5A3C7E9B // 第一轮 XOR
deviceXorKey2 uint32 = 0xE7B2A4C3 // 第二轮 XOR
)
// bitShuffle 交错重排 32 位的比特位,打散高低位的关联
func bitShuffle(v uint32) uint32 {
var result uint32
// 把偶数位放到高16位奇数位放到低16位
for i := 0; i < 16; i++ {
result |= ((v >> (2 * i)) & 1) << (16 + i) // 偶数位 → 高半
result |= ((v >> (2*i + 1)) & 1) << i // 奇数位 → 低半
}
return result
}
// bitUnshuffle 是 bitShuffle 的逆操作
func bitUnshuffle(v uint32) uint32 {
var result uint32
for i := 0; i < 16; i++ {
result |= ((v >> (16 + i)) & 1) << (2 * i) // 高半 → 偶数位
result |= ((v >> i) & 1) << (2*i + 1) // 低半 → 奇数位
}
return result
}
// DeviceIdToHash encodes a device id to an 8-char uppercase hex string.
// Algorithm mirrors frontend: id XOR salt → hex.
// e.g. 1 → "5A3C7E9A", 42 → "5A3C7EA1"
// Uses multiply-xor-shuffle to fully scatter sequential IDs.
// e.g. 1 → "83AEF73C", 2 → "D603916F" (no visible pattern)
func DeviceIdToHash(id int64) string {
return strings.ToUpper(fmt.Sprintf("%08x", uint32(id)^deviceHashSalt))
n := uint32(id)
n ^= deviceXorKey1 // step 1: XOR
n *= deviceMultiplier // step 2: 乘法扩散(模 2^32
n = bitShuffle(n) // step 3: 比特位交错
n ^= deviceXorKey2 // step 4: 再次 XOR
return strings.ToUpper(fmt.Sprintf("%08x", n))
}
// HashToDeviceId decodes an 8-char hex hash back to a device id.
@ -21,5 +55,9 @@ func HashToDeviceId(hash string) (int64, error) {
if err != nil {
return 0, err
}
return int64(n ^ deviceHashSalt), nil
n ^= deviceXorKey2 // reverse step 4
n = bitUnshuffle(n) // reverse step 3
n *= deviceInverse // reverse step 2: 乘法逆元
n ^= deviceXorKey1 // reverse step 1
return int64(n), nil
}

View File

@ -276,13 +276,13 @@ func main() {
SELECT user_id AS uid FROM ` + "`order`" + ` WHERE status = ? AND user_id > 0
UNION
SELECT user_id AS uid FROM apple_iap_transactions WHERE user_id > 0
UNION
SELECT user_id AS uid FROM user_subscribe WHERE user_id > 0
) t
INNER JOIN user_subscribe s ON s.user_id = t.uid
INNER JOIN user u ON u.id = t.uid
WHERE u.id NOT IN (
WHERE (s.expire_time IS NULL OR s.expire_time > NOW())
AND u.id NOT IN (
SELECT user_id FROM user_auth_methods WHERE auth_type = 'email' AND auth_identifier = 'devneeds52@gmail.com'
)
)
ORDER BY t.uid
`, orderStatusCompleted).Scan(&paidIDs).Error
if err != nil {

View File

@ -10,3 +10,14 @@ TRUNCATE TABLE user_device_online_record;
TRUNCATE TABLE user_family;
TRUNCATE TABLE user_family_member;
TRUNCATE TABLE user_subscribe;
docker exec ppanel-mysql mysql -uroot -p hifast -e "
SELECT id, referer_id, refer_code, created_at
FROM user
WHERE refer_code = 'uuD58Gs9'
ORDER BY id DESC
LIMIT 10;
"
docker logs ppanel-server 2>&1 | grep "1519\|bind_invite\|BindInviteCode" | tail -20

View File

@ -25,7 +25,7 @@ certbot certonly --manual --preferred-challenges dns -d airoport.win -d "*.airop
| docker exec -i ppanel-mysql mysql -uroot -pjpcV41ppanel
go run scripts/migrate_paid_users.go -src 'root:rootpassword@tcp(127.0.0.1:3306)/ppanel?charset=utf8mb4&parseTime=True&loc=Local' -dst 'root:jpcV41ppanel@tcp(103.150.215.44:3306)/hifast?charset=utf8mb4&parseTime=True&loc=Local' -clean
go run scripts/migrate_paid_users.go -src 'root:rootpassword@tcp(127.0.0.1:3306)/ppanel?charset=utf8mb4&parseTime=True&loc=Local' -dst 'root:jpcV41ppanel@tcp(154.12.35.103:3306)/ppanel?charset=utf8mb4&parseTime=True&loc=Local' -clean