
BLE UUID Generator & Converter
Generate a 128-bit base UUID with its service and characteristic UUIDs, convert 16-, 32-, and 128-bit forms and firmware byte arrays, and copy the format each stack expects.
Generate a service and its characteristics
One random base, with sequential values in the 16-bit field at characters 5 to 8.
Random RFC 9562 version 4 UUID from crypto.getRandomValues, created in your browser. Paste your own 128-bit base to use it instead.
Convert a UUID
Address your characteristics from SimpleBLE
Read, write, and subscribe to characteristics by service and characteristic UUID with SimpleBLE.
Why custom services use 128-bit UUIDs
Every service, characteristic, and descriptor in a GATT database has a UUID that identifies its type. The short 16-bit form is reserved for values the Bluetooth SIG assigns: adopted services such as Heart Rate 0x180D, characteristics, descriptors, and member UUIDs allocated to companies. A product team does not pick a 16-bit value for its own attributes.
Custom services and characteristics without a SIG allocation use full 128-bit UUIDs, and no registry is involved. The Core Specification describes UUIDs as values that can be created independently, with a negligible probability that two of them match. A version 4 UUID from a cryptographic random source carries 122 random bits, and that is the form this tool generates.
The cost is size. A 128-bit UUID takes 16 bytes in ATT PDUs and advertising data, where a 16-bit UUID takes 2. A legacy advertising PDU holds 31 bytes of advertising data, and a list with one 128-bit service UUID uses 18 of them, including its length and type bytes.
Why custom UUIDs avoid the Bluetooth Base UUID
The Core Specification (Vol 3, Part B, Section 2.5.1) pre-allocates a range of UUIDs for often-used, registered purposes. The first value in the range is the Bluetooth Base UUID, 00000000-0000-1000-8000-00805F9B34FB, and every 16- or 32-bit UUID is an alias for a 128-bit value in it:
128_bit_value = 16_bit_value × 2^96 + Bluetooth_Base_UUIDHeart Rate 0x180D is therefore 0000180D-0000-1000-8000-00805F9B34FB, and any value of the form xxxxxxxx-0000-1000-8000-00805F9B34FB is the alias of a 32-bit value. A custom attribute placed in this range can collide with an existing or future SIG assignment, and tools that resolve assigned numbers treat it as a SIG value. The converter flags every UUID in the range.
A random version 4 UUID cannot land in the range. The Base UUID carries version 1 in the version field, the 1 in -1000-, and a version 4 UUID always carries 4 in that position.
Canonical strings and on-air byte order
The canonical string writes the 16 bytes of a UUID most significant first, in groups of 8, 4, 4, 4, and 12 hex digits. ATT and GATT send multi-octet fields least significant octet first (Core Specification Vol 3, Part F, Section 3.3.1 and Part G, Section 2.4), so a UUID travels with its 16 bytes reversed. Advertising data uses the same order. For the Nordic UART Service:
Canonical string 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
Canonical bytes 6E 40 00 01 B5 A3 F3 93 E0 A9 E5 0E 24 DC CA 9E
On-air bytes 9E CA DC 24 0E E5 A9 E0 93 F3 A3 B5 01 00 40 6EThe whole 16-byte value is reversed, not each group. A 16-bit UUID follows the same rule: Heart Rate 0x180D appears on air as 0D 18.
Firmware SDKs store 128-bit UUIDs as little-endian byte arrays, so an array copied from firmware or a packet capture reads backwards against the canonical string. Reading it in the wrong order still produces a well-formed UUID, and discovery then fails to find the attribute. In the converter, select on-air order for arrays from firmware and captures, and canonical order for bytes written in string order.
Deriving a UUID family from one base
Vendor profiles commonly share one base across a service and its characteristics, and vary a 16-bit field in canonical bytes 2 and 3, characters 5 to 8 of the string. The Nordic UART Service uses this layout, and Nordic documents the service UUID with a 16-bit offset of 0x0001:
Service 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
RX 6E400002-B5A3-F393-E0A9-E50E24DCCA9E
TX 6E400003-B5A3-F393-E0A9-E50E24DCCA9EThe nRF5 SoftDevice API is built on the same layout. sd_ble_uuid_vs_add registers a base, and ble_uuid_t supplies the 16-bit value for bytes 12 and 13 of the little-endian array, which are bytes 2 and 3 of the canonical string. One registered base addresses 65,536 UUIDs.
A family keeps related attributes recognizable in logs and code. Each derived UUID is still a complete 128-bit identifier, and clients compare all 128 bits. Derived values keep the version and variant bits of the base, which sit in bytes 6 and 8, and distinct 16-bit values always produce distinct UUIDs. Record the assigned values in source control and do not reuse a retired value for a different attribute.
The format each stack expects
- Zephyr and nRF Connect SDK.
BT_UUID_128_ENCODEtakes the five groups of the canonical string as numbers and emits the bytes little-endian. Wrap it inBT_UUID_DECLARE_128orBT_UUID_INIT_128. SIG values useBT_UUID_DECLARE_16. - nRF5 SDK.
ble_uuid128_tholds the base as little-endian bytes.sd_ble_uuid_vs_addregisters it, ignoring bytes 12 and 13, and returns a type index. Each attribute is then able_uuid_twith its 16-bit value and that type. SIG values useBLE_UUID_TYPE_BLE. - ESP-IDF with Bluedroid.
esp_bt_uuid_twithlenset toESP_UUID_LEN_128anduuid.uuid128holding little-endian bytes. SIG values useESP_UUID_LEN_16anduuid.uuid16. - ESP-IDF with NimBLE.
BLE_UUID128_INITtakes the 16 bytes in little-endian order. SIG values useBLE_UUID16_INIT. - SimpleBLE. Services and characteristics are addressed by full 128-bit UUID strings, written in lowercase as in the SimpleBLE documentation:
0000180f-0000-1000-8000-00805f9b34fbfor the Battery service. A 16-bit value such as180fis passed in its 128-bit form. - Captures and HCI logs. Raw bytes appear in on-air order. Compare them against the on-air output, not the canonical string.
The converter emits each of these forms. To identify an assigned or known vendor UUID, open it in the GATT UUID lookup.