# fix(convert): zero-pad each channel in RgbToHex ## Problem `RgbToHex` (and its alias `Rgb2hex`) does not zero-pad channel values below `0x10`, so a single hex digit is emitted for those channels: ```go color.RgbToHex([]int{1, 2, 3}) // "123" , want "010203" color.RgbToHex([]int{0, 0, 0}) // "000" , want "000000" color.RgbToHex([]int{10, 11, 12}) // "0a0b0c" -> actually "abc" ``` This breaks two contracts: 1. The round-trip with `HexToRgb` is no longer an identity for colors with any channel below 16: ```go color.RgbToHex(color.HexToRgb("010203")) // "123", not "010203" ``` 2. `Rgb2basic` looks a color up in `hex2basicMap`, whose keys are all fixed-width 6-digit hex strings (e.g. "000000"). Because `RgbToHex(0,0,0)` returns "000", pure black never matches the fast-path map and silently falls through to the approximate `RgbToAnsi`. The sibling converter `RgbTo256` already builds its hex key with `fmt.Sprintf("%02x%02x%02x", ...)`, so this is an inconsistency within the same file. ## Root cause `convert.go`, `RgbToHex`: ```go for _, v := range rgb { hexNodes = append(hexNodes, strconv.FormatInt(int64(v), 16)) } ``` `strconv.FormatInt(_, 16)` produces the minimal representation, i.e. one digit for values 0-15. ## Fix Format each channel as a fixed two-digit hex value: ```go hexNodes = append(hexNodes, fmt.Sprintf("%02x", v)) ``` `fmt` is already imported in the file. Existing values >= 16 are unchanged. ## Test Extended `TestRgbToHex` in `utils_test.go` with small-channel cases (`{0,0,0}`, `{1,2,3}`, `{10,11,12}`) and an explicit `RgbToHex(HexToRgb(hex)) == hex` round-trip check. - Gate: `go test ./` -> ok (PASS) - `go vet ./...` -> exit 0 - `go build ./...` -> exit 0 Counterfactual: reverting `RgbToHex` to `strconv.FormatInt(int64(v), 16)` makes the new test fail with `expect: "abc"` vs `actual: "0a0b0c"`. Note: `gofmt -l convert.go` reports the file, but this is pre-existing (a doc comment near line 866, unrelated to this change and present on the base commit). The changed region is gofmt-clean, so unrelated lines were intentionally left untouched.