Skip to main content

minecraft_java_rs_core/utils/
auth.rs

1/// Generates a deterministic offline UUID from a username.
2///
3/// Uses a FNV-1a–inspired mix to produce a UUID v3-style string that is
4/// stable across calls for the same username. Suitable for offline-mode
5/// Minecraft sessions where a real Microsoft account is not available.
6pub fn offline_uuid(username: &str) -> String {
7    let mut a = 0xcbf29ce484222325u64;
8    let mut b = 0x14650fb0739d0383u64;
9    for byte in username.bytes() {
10        a ^= byte as u64;
11        a = a.wrapping_mul(0x100000001b3);
12        b ^= a;
13        b = b.wrapping_mul(0x517cc1b727220a95);
14    }
15    format!(
16        "{:08x}-{:04x}-3{:03x}-{:04x}-{:012x}",
17        (b >> 32) as u32,
18        (b >> 16) as u16,
19        b as u16 & 0x0fff,
20        ((a >> 48) as u16 & 0x3fff) | 0x8000,
21        a & 0x0000_ffff_ffff_ffff
22    )
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28
29    #[test]
30    fn same_username_same_uuid() {
31        assert_eq!(offline_uuid("Steve"), offline_uuid("Steve"));
32    }
33
34    #[test]
35    fn different_usernames_different_uuids() {
36        assert_ne!(offline_uuid("Steve"), offline_uuid("Alex"));
37    }
38
39    #[test]
40    fn output_is_valid_uuid_format() {
41        let u = offline_uuid("Player");
42        let parts: Vec<&str> = u.split('-').collect();
43        assert_eq!(parts.len(), 5);
44        assert_eq!(parts[0].len(), 8);
45        assert_eq!(parts[1].len(), 4);
46        assert_eq!(parts[2].len(), 4);
47        assert_eq!(parts[3].len(), 4);
48        assert_eq!(parts[4].len(), 12);
49    }
50}