indexing description: "UUID helper tools" license: "MIT license (see ../license.txt)" author: "Beat Strasser " date: "$Date$" revision: "$Revision$" class P2P_UUID_TOOLS inherit P2P_RANDOM_SHARED feature {NONE} -- UUID Uuid_bytes_count: INTEGER is 16 create_random_uuid (bytes: ARRAY [NATURAL_8]; start_pos: INTEGER) is -- Write new version 4 IETF variant random UUID to `bytes' at position `start_pos' require Bytes_valid: bytes /= Void and bytes.count >= uuid_bytes_count Pos_valid: bytes.lower <= start_pos and start_pos <= bytes.upper - uuid_bytes_count + 1 local pos: INTEGER do from pos := start_pos until pos = start_pos + uuid_bytes_count loop bytes[pos] := rand.item.as_natural_8 rand.forth pos := pos + 1 end -- mask to produce a version 4 IETF variant random UUID bytes[start_pos + 6] := (bytes[start_pos + 6] & 0x0F) | 0x40 -- version 4 bytes[start_pos + 8] := (bytes[start_pos + 8] & 0x3F) | 0x80 -- IETF variant bytes[start_pos + 10] := (bytes[start_pos + 10] & 0x7F) | 0x80 -- multicast end parse_uuid_from_string (source: STRING; bytes: ARRAY [NATURAL_8]; start_pos: INTEGER) is -- Parse UUID from `source' and write to `bytes' at `start_pos'. Ignore dash chars in input. require Source_valid: source /= Void and source.count = 2 * uuid_bytes_count + source.occurrences ('-') Bytes_valid: bytes /= Void and bytes.count >= uuid_bytes_count Pos_valid: bytes.lower <= start_pos and start_pos <= bytes.upper - uuid_bytes_count + 1 local source_pos: INTEGER cropped: STRING do -- remove all dash chars from source cropped := source.twin cropped.prune_all ('-') -- internalize uuid from source_pos := 1 until source_pos > cropped.count loop bytes[start_pos + (source_pos // 2)] := hex_to_natural_8 (cropped.item (source_pos), cropped.item (source_pos + 1)) source_pos := source_pos + 2 end end uuid_string (bytes: ARRAY [NATURAL_8]; start_pos: INTEGER): STRING is -- Hex string of uuid in `bytes' starting at `start_pos' require Bytes_valid: bytes /= Void and bytes.count >= uuid_bytes_count Pos_valid: bytes.lower <= start_pos and start_pos <= bytes.upper - uuid_bytes_count + 1 local pos: INTEGER do -- build hex string create Result.make (2 * uuid_bytes_count + 4) from pos := start_pos until pos >= start_pos + uuid_bytes_count loop Result.append (bytes[pos].to_hex_string) pos := pos + 1 end -- insert dashs for nicer uuid output ;) Result.insert_character ('-', 21) Result.insert_character ('-', 17) Result.insert_character ('-', 13) Result.insert_character ('-', 9) ensure Result_set: Result /= Void and Result.count = 2 * uuid_bytes_count + 4 end feature {NONE} -- Implementation hex_to_natural_8 (msc, lsc: CHARACTER): NATURAL_8 is -- Converts hex characters `msb' and `lsb' to a NATURAL_8 require Valid_hex: msc.is_hexa_digit and lsc.is_hexa_digit local n: INTEGER do if msc.is_digit then n := msc.code - ('0').code elseif msc >= 'a' then n := msc.code - ('a').code + 10 else n := msc.code - ('A').code + 10 end if lsc.is_digit then n := (n |<< 4) + lsc.code - ('0').code elseif lsc >= 'a' then n := (n |<< 4) + lsc.code - ('a').code + 10 else n := (n |<< 4) + lsc.code - ('A').code + 10 end Result := n.to_natural_8 end end