code, game, proofs

Color-Encoded Information Protocol

Version 1.1

Table of Contents

  1. Introduction
  2. Objectives
  3. Rationale
    1. Color Term Choices
    2. Ordering of Color Index
    3. Use of ASCII Characters for Keys
    4. Use of Numbers for Values
    5. Key/Value Pair Representation
  4. Color to Number Mapping
  5. Protocol Description
    1. Encoding
    2. Decoding
  6. Special Commands and Message Buffering
  7. Use Cases
  8. Future Work and Recommendations

1. Introduction

The Color-Encoded Information Protocol (CEIP) aims to provide a standardized way of representing digital information using LEGO bricks of specific colors. With the integration of 12 distinctive colors, this protocol offers a medium to encode and decode key/value pairs, where the key is an ASCII character, and the value is a number between 0 and 143.

2. Objectives

  1. Encode key/value pairs where the key is a printable ASCII character, and the value is a number between 0-143.
  2. Support a buffer for message data.
  3. Ensure the protocol is human-readable and interpretable.
  4. Allow the storage of various types of data, including game states and object attributes.

3. Rationale

3.1 Color Term Choices

The protocol utilizes 12 easily distinguishable colors that are universally recognizable and available in LEGO sets.

3.2 Ordering of Color Index

Colors are indexed from 0 to 11 in alphabetical order for ease of standardization and recollection.

3.3 Use of ASCII Characters for Keys

ASCII characters in the printable range (32-126) are used for the keys to ensure wide compatibility and ease of use. They are globally recognized and accommodate a rich variety of symbols and letters.

3.4 Use of Numbers for Values

The values range from 0 to 143. This is intentionally designed to match the 12×12 combinations that can be formed using the 12 unique colors (12 * 12 = 144, ranging from 0 to 143).

3.5 Key/Value Pair Representation

Each key/value pair is represented as a set of four LEGO bricks of specific colors. The first two bricks represent the ASCII character key, and the next two represent the value as a number between 0 and 143. This ensures each key/value pair can be consistently encoded and decoded using four LEGO bricks.

4. Color to Number Mapping

  • “Aqua”: 0
  • “Black”: 1
  • “Blue”: 2
  • “Brown”: 3
  • “Gray”: 4
  • “Green”: 5
  • “Orange”: 6
  • “Pink”: 7
  • “Purple”: 8
  • “Red”: 9
  • “White”: 10
  • “Yellow”: 11

5. Protocol Description

5.1 Encoding

Encoding of key/value pairs follows the predefined mappings, using four bricks per pair. The first two bricks encode the ASCII key, while the next two encode the value between 0 and 143.

5.2 Decoding

Decoding reverses the encoding process, translating each set of four bricks back into a key/value pair.

6. Special Commands and Message Buffering

If two bricks at the beginning of a row appear in sequence as Aqua followed by Blue (which decodes to the ASCII code point for ␂ or Start of Text), this signals the start of a message buffer. The buffer continues until another ␂ character is encountered or the row ends.

7. Use Cases

  • Storing game states
  • Embedding attributes in physical objects
  • Encoding messages or notes
  • Educational implementations

8. Future Work and Recommendations

  • Validation and error-correction features
  • Protocol optimizations
  • Compatibility extensions

Python Implementation

class ColorCode:
def __init__(self):
self.COLORS = {
"Aqua": 0,
"Black": 1,
"Blue": 2,
"Brown": 3,
"Gray": 4,
"Green": 5,
"Orange": 6,
"Pink": 7,
"Purple": 8,
"Red": 9,
"White": 10,
"Yellow": 11,
}
self.COLORS_INDEX = {v: k for k, v in self.COLORS.items()}
def text_encode(self, char):
if not 32 <= ord(char) <= 126:
raise ValueError("Character should be a printable ASCII character")
code_point = ord(char)
return self.number_encode(code_point)
def text_decode(self, color_list):
number = self.number_decode(color_list)
if not 32 <= number <= 126:
raise ValueError("Invalid color list for a single ASCII character")
return chr(number)
def number_encode(self, number):
if number < 0 or number > 144:
raise ValueError("Number should be in the range 0-143")
digit1, digit2 = divmod(number, 12)
color1 = self.COLORS_INDEX[digit1]
color2 = self.COLORS_INDEX[digit2]
return [color1, color2]
def number_decode(self, color_list):
if len(color_list) != 2:
raise ValueError("Invalid color list length for a single number")
digit1 = self.COLORS[color_list[0]]
digit2 = self.COLORS[color_list[1]]
return digit1 * 12 + digit2
def encode(self, data):
if not all(isinstance(k, str) and len(k) == 1 and 32 <= ord(k) <= 126 for k in data.keys()):
raise ValueError("All keys should be single printable ASCII characters")
if not all(isinstance(v, int) and 0 <= v <= 143 for v in data.values()):
raise ValueError("All values should be integers between 0 and 143")
encoded_list = []
for k, v in data.items():
encoded_key = self.text_encode(k)
encoded_value = self.number_encode(v)
encoded_list.extend(encoded_key + encoded_value)
return encoded_list
def decode(self, encoded_list):
if len(encoded_list) % 4 != 0:
raise ValueError("Encoded list length should be a multiple of 4")
decoded_dict = {}
for i in range(0, len(encoded_list), 4):
decoded_key = self.text_decode(encoded_list[i:i + 2])
decoded_value = self.number_decode(encoded_list[i + 2:i + 4])
decoded_dict[decoded_key] = decoded_value
return decoded_dict
# Example usage
if __name__ == "__main__":
color_code = ColorCode()
STX = 2 # ASCII Start of Text character
STX_color = color_code.number_encode(STX)
print("Start of Text colors:", STX_color)
data = {'x': 30, 'y': 15, 'z': 101}
encoded_data = color_code.encode(data)
print("Encoded:", encoded_data)
decoded_only = color_code.decode(encoded_data)
print("Decoded:", decoded_only)