refactor dispersion_tutorial.ipynb
This commit is contained in:
@@ -1,36 +1,71 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Dispersion"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"from src.user_keypad import UserKeypad\n",
|
||||
"from src.utils import random_property_rotation\n",
|
||||
"from IPython.display import Markdown, display\n",
|
||||
"from src.models import KeypadSize\n",
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"def random_property_rotation(\n",
|
||||
" user_keypad: np.ndarray,\n",
|
||||
" prop_rotation: list[int]\n",
|
||||
") -> np.ndarray:\n",
|
||||
" transposed = user_keypad.T\n",
|
||||
" if len(prop_rotation) != len(transposed):\n",
|
||||
" raise ValueError(\"prop_rotation must be the same length as the number of properties\")\n",
|
||||
" for idx, prop_set in enumerate(transposed):\n",
|
||||
" rotation = prop_rotation[idx]\n",
|
||||
" rotation = rotation % len(prop_set) if len(prop_set) > 0 else 0\n",
|
||||
" transposed[idx] = np.roll(prop_set, rotation)\n",
|
||||
" return transposed.T\n",
|
||||
"\n",
|
||||
"def keypad_md_table(keypad_list: np.ndarray, keypad_size: KeypadSize) -> str:\n",
|
||||
" assert (keypad_size.total_props == len(keypad_list))\n",
|
||||
" keypad = keypad_list.reshape(-1, keypad_size.props_per_key)\n",
|
||||
" table = \"|key|\" + \"\".join([f\"set{idx}|\" for idx in range(keypad_size.props_per_key)])\n",
|
||||
" table = \"||\" + \"\".join([f\"position {idx}|\" for idx in range(keypad_size.props_per_key)])\n",
|
||||
" table += \"\\n|\" + \"\".join(\"-|\" for _ in range(keypad_size.props_per_key + 1))\n",
|
||||
"\n",
|
||||
" for key in range(keypad_size.numb_of_keys):\n",
|
||||
" table += f\"\\n|key{key+1}|\"\n",
|
||||
" table += f\"\\n|key {key}|\"\n",
|
||||
" table += \"|\".join([str(prop) for prop in keypad[key]])\n",
|
||||
" table += \"|\"\n",
|
||||
" return table\n",
|
||||
" return table"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T16:15:24.214098Z",
|
||||
"start_time": "2025-03-20T16:15:24.207220Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"execution_count": 80
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": [
|
||||
"## Keypad Dispersion\n",
|
||||
"\n",
|
||||
"Keypad dispersion refers to an operation that redistributes the properties assigned to each key on a keypad, ensuring that no property shares a key with a property that was previously adjacent to it.\n",
|
||||
"Keypads are only dispersable if `numb_of_keys <= properites_per_key`\n",
|
||||
"\n",
|
||||
"A keypad dispersion is completed in two steps:\n",
|
||||
"1. Create a property rotation array; a randomly permuted subset of indices, selected without replacement from a range equal to the number of keys on a keypad, with its length truncated to match the number of properties assigned per key.\n",
|
||||
"2. Rotate each position, similar to a ring or combination lock, by a distance equal to its corresponding value in the property rotation array."
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T16:15:24.225459Z",
|
||||
"start_time": "2025-03-20T16:15:24.220286Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"keypad_size = KeypadSize(numb_of_keys=5, props_per_key=4)\n",
|
||||
"props = [1, 10, 11, 100]\n",
|
||||
"keypad = []\n",
|
||||
@@ -38,90 +73,98 @@
|
||||
" keypad.extend([key_numb * prop for prop in props])\n",
|
||||
"\n",
|
||||
"demo_interface = UserKeypad(keypad_size=keypad_size, keypad=np.array(keypad))\n",
|
||||
"\n",
|
||||
"display(Markdown(f\"\"\"\n",
|
||||
"## Example Keypad\n",
|
||||
"{keypad_size.numb_of_keys} X {keypad_size.props_per_key} keypad ({keypad_size.numb_of_keys} keys, {keypad_size.props_per_key} properties per key).\n",
|
||||
"\"\"\"))\n",
|
||||
"display(Markdown(keypad_md_table(demo_interface.keypad, keypad_size)))\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-14T14:34:55.702615Z",
|
||||
"start_time": "2025-03-14T14:34:55.694963Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
],
|
||||
"text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|1|10|11|100|\n|key2|2|20|22|200|\n|key3|3|30|33|300|\n|key4|4|40|44|400|\n|key5|5|50|55|500|"
|
||||
"text/markdown": "\n## Example Keypad\n5 X 4 keypad (5 keys, 4 properties per key).\n"
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"execution_count": 4
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"demo_interface_matrix = demo_interface.keypad.reshape(-1, demo_interface.keypad_size.props_per_key)\n",
|
||||
"shuffled_keys = np.random.permutation(demo_interface_matrix)\n",
|
||||
"shuffled_keys_list = shuffled_keys.reshape(-1)\n",
|
||||
"display(Markdown(keypad_md_table(shuffled_keys_list, keypad_size)))"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-14T14:34:55.718161Z",
|
||||
"start_time": "2025-03-14T14:34:55.714512Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
],
|
||||
"text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|1|10|11|100|\n|key2|4|40|44|400|\n|key3|3|30|33|300|\n|key4|2|20|22|200|\n|key5|5|50|55|500|"
|
||||
"text/markdown": "||position 0|position 1|position 2|position 3|\n|-|-|-|-|-|\n|key 0|1|10|11|100|\n|key 1|2|20|22|200|\n|key 2|3|30|33|300|\n|key 3|4|40|44|400|\n|key 4|5|50|55|500|"
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"execution_count": 5
|
||||
"execution_count": 81
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "### Create Property Rotation Array"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"prop_rotation = np.random.choice(range(keypad_size.numb_of_keys), size=keypad_size.props_per_key, replace=False)\n",
|
||||
"dispersed_interface = random_property_rotation(\n",
|
||||
" shuffled_keys,\n",
|
||||
" prop_rotation\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"display(Markdown(keypad_md_table(dispersed_interface.reshape(-1), keypad_size)))\n"
|
||||
"print(f\"Property Rotation: {prop_rotation}\")\n"
|
||||
],
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-14T14:34:55.731332Z",
|
||||
"start_time": "2025-03-14T14:34:55.728135Z"
|
||||
"end_time": "2025-03-20T16:15:24.240606Z",
|
||||
"start_time": "2025-03-20T16:15:24.237773Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Property Rotation: [4 3 2 0]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 82
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"cell_type": "markdown",
|
||||
"source": "### Apply the Rotation"
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T16:15:24.256086Z",
|
||||
"start_time": "2025-03-20T16:15:24.253226Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"dispersed_interface = random_property_rotation(\n",
|
||||
" demo_interface.keypad.reshape(-1, keypad_size.props_per_key),\n",
|
||||
" prop_rotation\n",
|
||||
")\n",
|
||||
"display(Markdown(keypad_md_table(dispersed_interface.reshape(-1), keypad_size)))"
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
],
|
||||
"text/markdown": "|key|set0|set1|set2|set3|\n|-|-|-|-|-|\n|key1|5|30|44|100|\n|key2|1|20|33|400|\n|key3|4|50|22|300|\n|key4|3|10|55|200|\n|key5|2|40|11|500|"
|
||||
"text/markdown": "||position 0|position 1|position 2|position 3|\n|-|-|-|-|-|\n|key 0|2|30|44|100|\n|key 1|3|40|55|200|\n|key 2|4|50|11|300|\n|key 3|5|10|22|400|\n|key 4|1|20|33|500|"
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"execution_count": 6
|
||||
"execution_count": 83
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.292663Z",
|
||||
"start_time": "2025-03-20T12:00:21.253426Z"
|
||||
"end_time": "2025-03-20T15:13:44.080558Z",
|
||||
"start_time": "2025-03-20T15:13:44.076372Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"execution_count": 2
|
||||
"execution_count": 41
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
@@ -53,12 +53,12 @@
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.298357Z",
|
||||
"start_time": "2025-03-20T12:00:21.296258Z"
|
||||
"end_time": "2025-03-20T15:13:44.090939Z",
|
||||
"start_time": "2025-03-20T15:13:44.088281Z"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"execution_count": 3
|
||||
"execution_count": 42
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -112,8 +112,8 @@
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.317747Z",
|
||||
"start_time": "2025-03-20T12:00:21.306163Z"
|
||||
"end_time": "2025-03-20T15:13:44.107060Z",
|
||||
"start_time": "2025-03-20T15:13:44.100773Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -121,30 +121,30 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Customer Position Key: [37938 42486 36680 47679 5944 46439]\n",
|
||||
"Customer Position Key: [22504 45127 46010 30773 46509 63084]\n",
|
||||
"Customer Properties Key:\n",
|
||||
"[14469 12272 54942 53713 60529 64319]\n",
|
||||
"[49129 65121 60219 33860 48996 57925]\n",
|
||||
"[61464 3328 59612 33957 62738 42039]\n",
|
||||
"[ 3074 46306 41956 4712 59250 7730]\n",
|
||||
"[23724 39640 530 27472 33903 26824]\n",
|
||||
"[38076 5253 43656 24035 57980 18197]\n",
|
||||
"[56754 21362 27799 42374 57145 46164]\n",
|
||||
"[56031 10476 13741 23847 57450 42577]\n",
|
||||
"[63205 55476 58864 29925 9463 58182]\n",
|
||||
"[61997 24583 9269 19956 55576 32892]\n",
|
||||
"Position to Properties Map:\n",
|
||||
"37938: [14469 49129 61464 3074 23724]\n",
|
||||
"42486: [12272 65121 3328 46306 39640]\n",
|
||||
"36680: [54942 60219 59612 41956 530]\n",
|
||||
"47679: [53713 33860 33957 4712 27472]\n",
|
||||
"5944: [60529 48996 62738 59250 33903]\n",
|
||||
"46439: [64319 57925 42039 7730 26824]\n"
|
||||
"22504: [38076 56754 56031 63205 61997]\n",
|
||||
"45127: [ 5253 21362 10476 55476 24583]\n",
|
||||
"46010: [43656 27799 13741 58864 9269]\n",
|
||||
"30773: [24035 42374 23847 29925 19956]\n",
|
||||
"46509: [57980 57145 57450 9463 55576]\n",
|
||||
"63084: [18197 46164 42577 58182 32892]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 4
|
||||
"execution_count": 43
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.325478Z",
|
||||
"start_time": "2025-03-20T12:00:21.322970Z"
|
||||
"end_time": "2025-03-20T15:13:44.127687Z",
|
||||
"start_time": "2025-03-20T15:13:44.125028Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -161,16 +161,16 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Position Value to Icons Map:\n",
|
||||
"37938: ['😀' '🥺' '🤔' '🐱' '🦄']\n",
|
||||
"42486: ['😂' '😡' '🙃' '🐶' '🌟']\n",
|
||||
"36680: ['🥳' '😱' '😇' '🦁' '⚡']\n",
|
||||
"47679: ['😍' '🤯' '🤖' '🐻' '🔥']\n",
|
||||
"5944: ['🤓' '🥰' '👽' '🐸' '🍕']\n",
|
||||
"46439: ['😎' '😴' '👾' '🐙' '🎉']\n"
|
||||
"22504: ['😀' '🥺' '🤔' '🐱' '🦄']\n",
|
||||
"45127: ['😂' '😡' '🙃' '🐶' '🌟']\n",
|
||||
"46010: ['🥳' '😱' '😇' '🦁' '⚡']\n",
|
||||
"30773: ['😍' '🤯' '🤖' '🐻' '🔥']\n",
|
||||
"46509: ['🤓' '🥰' '👽' '🐸' '🍕']\n",
|
||||
"63084: ['😎' '😴' '👾' '🐙' '🎉']\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 5
|
||||
"execution_count": 44
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -194,8 +194,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.349267Z",
|
||||
"start_time": "2025-03-20T12:00:21.342655Z"
|
||||
"end_time": "2025-03-20T15:13:44.156638Z",
|
||||
"start_time": "2025-03-20T15:13:44.150222Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -223,11 +223,11 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Key 0: ['🐱' '🐶' '😱' '😍' '🍕']\n",
|
||||
"Key 1: ['🦄' '😡' '⚡' '🤯' '🐸']\n",
|
||||
"Key 2: ['😀' '🙃' '😇' '🔥' '👽']\n",
|
||||
"Key 3: ['🥺' '😂' '🥳' '🐻' '🥰']\n",
|
||||
"Key 4: ['🤔' '🌟' '🦁' '🤖' '🤓']\n"
|
||||
"Key 0: ['🦄' '🦁' '🐻' '🤓' '👾']\n",
|
||||
"Key 1: ['🥺' '⚡' '🔥' '🍕' '🎉']\n",
|
||||
"Key 2: ['🐱' '😱' '🤖' '👽' '🐙']\n",
|
||||
"Key 3: ['😀' '🥳' '😍' '🐸' '😴']\n",
|
||||
"Key 4: ['🤔' '😇' '🤯' '🥰' '😎']\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -244,11 +244,11 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Key 0: [18 19 8 3 28]\n",
|
||||
"Key 1: [24 7 26 9 22]\n",
|
||||
"Key 2: [ 0 13 14 27 16]\n",
|
||||
"Key 3: [ 6 1 2 21 10]\n",
|
||||
"Key 4: [12 25 20 15 4]\n"
|
||||
"Key 0: [24 20 21 4 17]\n",
|
||||
"Key 1: [ 6 26 27 28 29]\n",
|
||||
"Key 2: [18 8 15 16 23]\n",
|
||||
"Key 3: [ 0 2 3 22 11]\n",
|
||||
"Key 4: [12 14 9 10 5]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -265,15 +265,15 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Key 0: [ 3074 46306 60219 53713 33903]\n",
|
||||
"Key 1: [23724 65121 530 33860 59250]\n",
|
||||
"Key 2: [14469 3328 59612 27472 62738]\n",
|
||||
"Key 3: [49129 12272 54942 4712 48996]\n",
|
||||
"Key 4: [61464 39640 41956 33957 60529]\n"
|
||||
"Key 0: [61997 58864 29925 57980 42577]\n",
|
||||
"Key 1: [56754 9269 19956 55576 32892]\n",
|
||||
"Key 2: [63205 27799 23847 57450 58182]\n",
|
||||
"Key 3: [38076 43656 24035 9463 46164]\n",
|
||||
"Key 4: [56031 13741 42374 57145 18197]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 6
|
||||
"execution_count": 45
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -286,8 +286,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.372390Z",
|
||||
"start_time": "2025-03-20T12:00:21.369564Z"
|
||||
"end_time": "2025-03-20T15:13:44.190448Z",
|
||||
"start_time": "2025-03-20T15:13:44.187214Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -306,14 +306,14 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"User Passcode Indices: [19, 28, 22, 18]\n",
|
||||
"User Passcode Icons: ['🐶' '🍕' '🐸' '🐱']\n",
|
||||
"User Passcode Server-side properties: [46306 33903 59250 3074]\n",
|
||||
"Selected Keys: [0, 0, 1, 0]\n"
|
||||
"User Passcode Indices: [4, 9, 5, 18]\n",
|
||||
"User Passcode Icons: ['🤓' '🤯' '😎' '🐱']\n",
|
||||
"User Passcode Server-side properties: [57980 42374 18197 63205]\n",
|
||||
"Selected Keys: [0, 4, 4, 2]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 7
|
||||
"execution_count": 46
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -326,8 +326,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.631111Z",
|
||||
"start_time": "2025-03-20T12:00:21.391841Z"
|
||||
"end_time": "2025-03-20T15:13:44.516570Z",
|
||||
"start_time": "2025-03-20T15:13:44.208909Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -344,17 +344,17 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Key 0: [0 7 2 3 4]\n",
|
||||
"Key 1: [ 6 25 26 27 28]\n",
|
||||
"Key 2: [24 19 20 21 16]\n",
|
||||
"Key 3: [12 13 8 9 10]\n",
|
||||
"Key 4: [18 1 14 15 22]\n",
|
||||
"Key 0: [18 20 27 10 11]\n",
|
||||
"Key 1: [24 14 15 22 29]\n",
|
||||
"Key 2: [12 2 21 28 23]\n",
|
||||
"Key 3: [ 0 26 9 16 17]\n",
|
||||
"Key 4: [6 8 3 4 5]\n",
|
||||
"Selected Keys\n",
|
||||
"[2, 1, 4, 4]\n"
|
||||
"[4, 3, 4, 0]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 8
|
||||
"execution_count": 47
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -364,8 +364,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:08:59.799827Z",
|
||||
"start_time": "2025-03-20T12:08:59.796887Z"
|
||||
"end_time": "2025-03-20T15:13:44.527802Z",
|
||||
"start_time": "2025-03-20T15:13:44.524844Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -384,22 +384,22 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Set Key 0: ['🐱' '🐶' '😱' '😍' '🍕']\n",
|
||||
"Confirm Key 0: ['🦄' '🐶' '🦁' '🐻' '👽']\n",
|
||||
"Overlapping icon 🐶\n",
|
||||
"Set Key 1: ['🐱' '🐶' '😱' '😍' '🍕']\n",
|
||||
"Confirm Key 1: ['🥺' '🌟' '⚡' '🔥' '🍕']\n",
|
||||
"Overlapping icon 🍕\n",
|
||||
"Set Key 2: ['🦄' '😡' '⚡' '🤯' '🐸']\n",
|
||||
"Confirm Key 2: ['🐱' '😂' '😇' '🤖' '🐸']\n",
|
||||
"Overlapping icon 🐸\n",
|
||||
"Set Key 3: ['🐱' '🐶' '😱' '😍' '🍕']\n",
|
||||
"Confirm Key 3: ['🐱' '😂' '😇' '🤖' '🐸']\n",
|
||||
"Set Key 0: ['🦄' '🦁' '🐻' '🤓' '👾']\n",
|
||||
"Confirm Key 0: ['🥺' '😱' '😍' '🤓' '😎']\n",
|
||||
"Overlapping icon 🤓\n",
|
||||
"Set Key 1: ['🤔' '😇' '🤯' '🥰' '😎']\n",
|
||||
"Confirm Key 1: ['😀' '⚡' '🤯' '👽' '👾']\n",
|
||||
"Overlapping icon 🤯\n",
|
||||
"Set Key 2: ['🤔' '😇' '🤯' '🥰' '😎']\n",
|
||||
"Confirm Key 2: ['🥺' '😱' '😍' '🤓' '😎']\n",
|
||||
"Overlapping icon 😎\n",
|
||||
"Set Key 3: ['🐱' '😱' '🤖' '👽' '🐙']\n",
|
||||
"Confirm Key 3: ['🐱' '🦁' '🔥' '🥰' '😴']\n",
|
||||
"Overlapping icon 🐱\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 15
|
||||
"execution_count": 48
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -419,8 +419,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.680780Z",
|
||||
"start_time": "2025-03-20T10:38:44.954840Z"
|
||||
"end_time": "2025-03-20T15:13:44.546871Z",
|
||||
"start_time": "2025-03-20T15:13:44.540903Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -430,13 +430,13 @@
|
||||
"user_prop_key_keypad = user_cipher.property_key.reshape(-1, keypad_size.props_per_key)"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 83
|
||||
"execution_count": 49
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.683788Z",
|
||||
"start_time": "2025-03-20T10:38:44.966571Z"
|
||||
"end_time": "2025-03-20T15:13:44.565168Z",
|
||||
"start_time": "2025-03-20T15:13:44.562664Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -447,21 +447,21 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Property Key:\n",
|
||||
"[[53739 14349 64971 50952 51008 37461]\n",
|
||||
" [45744 17444 29958 27397 60694 8069]\n",
|
||||
" [43064 47943 49025 5623 3145 4890]\n",
|
||||
" [ 1128 11012 53093 14232 26108 5391]\n",
|
||||
" [59341 47378 48497 6840 34437 29587]]\n"
|
||||
"[[21364 17750 43270 40570 2897 64106]\n",
|
||||
" [64901 60553 23487 56910 22974 27412]\n",
|
||||
" [49276 36687 58910 60854 56432 64908]\n",
|
||||
" [17816 7963 33663 13564 43318 39697]\n",
|
||||
" [ 6300 40793 34908 48633 47026 16580]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 84
|
||||
"execution_count": 50
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.684015Z",
|
||||
"start_time": "2025-03-20T10:38:44.983449Z"
|
||||
"end_time": "2025-03-20T15:13:44.583641Z",
|
||||
"start_time": "2025-03-20T15:13:44.581757Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -471,17 +471,17 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Passcode Key: [16245 48001 4534 55258 54613 15211 33171 56565 33961 50654]\n"
|
||||
"Passcode Key: [65482 44549 30799 45221 44404 5844 32654 14244 48015 17243]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 85
|
||||
"execution_count": 51
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.689867Z",
|
||||
"start_time": "2025-03-20T10:38:45.005712Z"
|
||||
"end_time": "2025-03-20T15:13:44.624946Z",
|
||||
"start_time": "2025-03-20T15:13:44.622774Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -491,17 +491,17 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Mask Key: [52084 24514 63626 6657 19669 39430 35626 25229 14824 63798]\n"
|
||||
"Mask Key: [36463 57168 30740 46459 21013 40282 33046 14986 26644 13]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 86
|
||||
"execution_count": 52
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.690242Z",
|
||||
"start_time": "2025-03-20T10:38:45.024649Z"
|
||||
"end_time": "2025-03-20T15:13:44.653291Z",
|
||||
"start_time": "2025-03-20T15:13:44.651215Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -511,17 +511,17 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Combined Position Key: [10235 12456 898 54650 50445 20719]\n"
|
||||
"Combined Position Key: [32765 21433 32527 38517 27021 45380]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 87
|
||||
"execution_count": 53
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.694701Z",
|
||||
"start_time": "2025-03-20T10:38:45.038985Z"
|
||||
"end_time": "2025-03-20T15:13:44.682695Z",
|
||||
"start_time": "2025-03-20T15:13:44.680482Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -531,17 +531,17 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"User Position Key = combined_pos_key XOR customer_pos_key: [ 3444 19636 47437 1440 7882 36903]\n"
|
||||
"User Position Key = combined_pos_key XOR customer_pos_key: [10261 58366 52405 60992 56352 18216]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 88
|
||||
"execution_count": 54
|
||||
},
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.696066Z",
|
||||
"start_time": "2025-03-20T10:38:45.056942Z"
|
||||
"end_time": "2025-03-20T15:13:44.713223Z",
|
||||
"start_time": "2025-03-20T15:13:44.710535Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -557,16 +557,16 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Combined Position to Properties Map:\n",
|
||||
"10235: [53739 45744 43064 1128 59341]\n",
|
||||
"12456: [14349 17444 47943 11012 47378]\n",
|
||||
"898: [64971 29958 49025 53093 48497]\n",
|
||||
"54650: [50952 27397 5623 14232 6840]\n",
|
||||
"50445: [51008 60694 3145 26108 34437]\n",
|
||||
"20719: [37461 8069 4890 5391 29587]\n"
|
||||
"32765: [21364 64901 49276 17816 6300]\n",
|
||||
"21433: [17750 60553 36687 7963 40793]\n",
|
||||
"32527: [43270 23487 58910 33663 34908]\n",
|
||||
"38517: [40570 56910 60854 13564 48633]\n",
|
||||
"27021: [ 2897 22974 56432 43318 47026]\n",
|
||||
"45380: [64106 27412 64908 39697 16580]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 89
|
||||
"execution_count": 55
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -583,8 +583,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.696415Z",
|
||||
"start_time": "2025-03-20T10:38:45.068009Z"
|
||||
"end_time": "2025-03-20T15:13:44.732450Z",
|
||||
"start_time": "2025-03-20T15:13:44.729920Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -596,7 +596,7 @@
|
||||
"encoded_mask = user_cipher.encode_base64_str(mask)"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 90
|
||||
"execution_count": 56
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -613,8 +613,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.696640Z",
|
||||
"start_time": "2025-03-20T10:38:45.087096Z"
|
||||
"end_time": "2025-03-20T15:13:45.055535Z",
|
||||
"start_time": "2025-03-20T15:13:44.751147Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -628,7 +628,7 @@
|
||||
"passcode_hash = bcrypt.hashpw(passcode_prehash, bcrypt.gensalt(rounds=12)).decode(\"utf-8\")"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 91
|
||||
"execution_count": 57
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -642,8 +642,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.696764Z",
|
||||
"start_time": "2025-03-20T10:38:45.326214Z"
|
||||
"end_time": "2025-03-20T15:13:45.367717Z",
|
||||
"start_time": "2025-03-20T15:13:45.061644Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -661,20 +661,20 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Key 0: [18 25 14 15 4 29]\n",
|
||||
"Key 1: [ 6 13 20 27 28 5]\n",
|
||||
"Key 2: [24 19 26 9 16 23]\n",
|
||||
"Key 3: [ 0 1 8 3 10 11]\n",
|
||||
"Key 4: [12 7 2 21 22 17]\n",
|
||||
"User Passcode: [28, 13, 9, 10]\n",
|
||||
"Key 0: [24 13 20 21 4 17]\n",
|
||||
"Key 1: [ 6 1 26 27 28 29]\n",
|
||||
"Key 2: [18 7 8 15 16 23]\n",
|
||||
"Key 3: [ 0 19 2 3 22 11]\n",
|
||||
"Key 4: [12 25 14 9 10 5]\n",
|
||||
"User Passcode: [4, 9, 5, 18]\n",
|
||||
"\n",
|
||||
"Selected Keys:\n",
|
||||
" [1, 1, 2, 3]\n",
|
||||
" [0, 4, 4, 2]\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 92
|
||||
"execution_count": 58
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -701,8 +701,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.696874Z",
|
||||
"start_time": "2025-03-20T10:38:45.567396Z"
|
||||
"end_time": "2025-03-20T15:13:45.379898Z",
|
||||
"start_time": "2025-03-20T15:13:45.377353Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -712,10 +712,10 @@
|
||||
"user = api.customers[customer_id].users[username]\n",
|
||||
"mask = user.cipher.decode_base64_str(user.enciphered_passcode.mask)\n",
|
||||
"ordered_user_position_key = mask ^ user.cipher.mask_key\n",
|
||||
"user_position_key = customer.cipher.position_key ^ user.cipher.combined_position_key\n"
|
||||
"user_position_key = customer.cipher.position_key ^ user.cipher.combined_position_key"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 93
|
||||
"execution_count": 59
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -727,15 +727,20 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T15:13:45.391901Z",
|
||||
"start_time": "2025-03-20T15:13:45.389499Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
"outputs": [],
|
||||
"execution_count": null,
|
||||
"source": [
|
||||
"passcode_position_indices = [int(np.where(user_position_key == pos)[0][0]) for pos in ordered_user_position_key[:passcode_len]]\n",
|
||||
"presumed_property_indices = customer.users[username].user_keypad.get_prop_idxs_by_keynumb_setidx(selected_keys_login, passcode_position_indices)\n",
|
||||
"assert passcode_property_indices == presumed_property_indices\n"
|
||||
]
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 60
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -745,8 +750,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.697134Z",
|
||||
"start_time": "2025-03-20T10:38:45.576610Z"
|
||||
"end_time": "2025-03-20T15:13:45.711702Z",
|
||||
"start_time": "2025-03-20T15:13:45.407474Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -755,7 +760,7 @@
|
||||
"assert valid_nkode"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 94
|
||||
"execution_count": 61
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -771,8 +776,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.697273Z",
|
||||
"start_time": "2025-03-20T10:38:45.816688Z"
|
||||
"end_time": "2025-03-20T15:13:46.331470Z",
|
||||
"start_time": "2025-03-20T15:13:45.715778Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -798,15 +803,15 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Old User Cipher and Mask\n",
|
||||
"mask: y8aMd+5qYcPVLETTcs2aHqx2hhk=, code: $2b$12$wMi7WGmlch8kWMYJ2v.FHOne1.YSQPqKU/itpBuycwSFyasryF/2u\n",
|
||||
"mask: xetVN/8taK1lhtrDjt4w0M4pprQ=, code: $2b$12$6JzDrPs.dAb0iOIvm8afKuwf.Z8qKtg89Nnhx..tlBOD5y1MYMR4y\n",
|
||||
"\n",
|
||||
"New User Cipher and Mask\n",
|
||||
"mask: aln5Su79utoVmqQXNCjYiUdwVYw=, code: $2b$12$gQf3UVa3cWMBy0CO0sBLyuJzdXGzg3qpNFMTD6MvycuR6N3gLFdgC\n",
|
||||
"mask: WsKTIcZVngijEKlMfoF2UG5Rz9I=, code: $2b$12$jvQ..z4tPFII5dLXP0D2LOPrypDSB7yoRH6E0SZPO/yIIcZVtgCTS\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"execution_count": 95
|
||||
"execution_count": 62
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -819,8 +824,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.697386Z",
|
||||
"start_time": "2025-03-20T10:38:46.293584Z"
|
||||
"end_time": "2025-03-20T15:13:46.344092Z",
|
||||
"start_time": "2025-03-20T15:13:46.339802Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -833,7 +838,7 @@
|
||||
"new_pos = customer.cipher.position_key"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 96
|
||||
"execution_count": 63
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -853,8 +858,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.697503Z",
|
||||
"start_time": "2025-03-20T10:38:46.310019Z"
|
||||
"end_time": "2025-03-20T15:13:46.361420Z",
|
||||
"start_time": "2025-03-20T15:13:46.359046Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -867,7 +872,7 @@
|
||||
" user.cipher.property_key = user.cipher.property_key ^ props_xor"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 97
|
||||
"execution_count": 64
|
||||
},
|
||||
{
|
||||
"metadata": {},
|
||||
@@ -880,8 +885,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"ExecuteTime": {
|
||||
"end_time": "2025-03-20T12:00:21.697608Z",
|
||||
"start_time": "2025-03-20T10:38:46.318482Z"
|
||||
"end_time": "2025-03-20T15:13:46.679562Z",
|
||||
"start_time": "2025-03-20T15:13:46.371777Z"
|
||||
}
|
||||
},
|
||||
"cell_type": "code",
|
||||
@@ -896,7 +901,7 @@
|
||||
" user.renew = False"
|
||||
],
|
||||
"outputs": [],
|
||||
"execution_count": 98
|
||||
"execution_count": 65
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
14
src/utils.py
14
src/utils.py
@@ -1,14 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
def random_property_rotation(
|
||||
user_keypad: np.ndarray,
|
||||
prop_rotation: list[int]
|
||||
) -> np.ndarray:
|
||||
transposed = user_keypad.T
|
||||
if len(prop_rotation) != len(transposed):
|
||||
raise ValueError("prop_rotation must be the same length as the number of properties")
|
||||
for idx, prop_set in enumerate(transposed):
|
||||
rotation = prop_rotation[idx]
|
||||
rotation = rotation % len(prop_set) if len(prop_set) > 0 else 0
|
||||
transposed[idx] = np.roll(prop_set, rotation)
|
||||
return transposed.T
|
||||
Reference in New Issue
Block a user