Как создать уникальный ID устройства и записать в EEPROM

progman
Offline
Зарегистрирован: 26.01.2019

Стоит задача чтобы каждый контроллео в мей сборке имел уникальный ID.

hardware id не доступно в большинстве arduino. Надо лепить свой аелоспиед.

Пока что придумал вот такую конструкцию:

1. при старте приложения оно читает первые 16+4 байт EEPROM ( последние 4 байта - контрольная сумма )

2. если не ОК то генерит случайные 16 байт , считает crc32 для них и пишет в память:

unsigned char uniqueid[20]            = { 0 };

void createUniqueId()
{
  for( int i = 0; i < 16; i++ )
    uniqueid[ i ] = analogRead( 0 );

  ((uint32_t*)&uniqueid[ 16 ])[0] = CRC32::calculate(uniqueid, 16);

  for (int i = 0; i < 20; i++)
    EEPROM.write( i, uniqueid[ i ]  );
}

void setup() 
{
 if( !checkUniqueId() )
   createUniqueId()
}

вопрос такой: насколько надежно конструкция uniqueid[ i ] = analogRead( 0 ); сгенерит 20 уникальных байт?

Можно ли как то прикинуть на какое кол-во устройств будут повторения?

Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи  прописать в память?

SLKH
Offline
Зарегистрирован: 17.08.2015

progman пишет:

 

Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи  прописать в память?

Есть секретный ресурс http://arduino.ru/forumy/programmirovanie , а на нем функция random() с готовым примером.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Подключаете ардуино к компу, а на компе генерерируете UUID и передаете ардуине для записи во флеш. Уникальность гарантируетчя.

progman
Offline
Зарегистрирован: 26.01.2019

SLKH пишет:

progman пишет:

 

Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи  прописать в память?

Есть секретный ресурс http://arduino.ru/forumy/programmirovanie , а на нем функция random() с готовым примером.

random - это псевдослучайный ГСЧ. секвенция "случайных" чисел будет одна и та же на всех устройствах.

а у analogRead слишком низкая энтропия - всего 10 бит

поэтому randomSeed(analogRead(0)); будет генерить одни и теже "случайные" числа на каждом из 1023 устройств.

риск что в одной партии сгенерится одинаковый серийный номер слишком велик

progman
Offline
Зарегистрирован: 26.01.2019

asam пишет:

Подключаете ардуино к компу, а на компе генерерируете UUID и передаете ардуине для записи во флеш. Уникальность гарантируетчя.

Это таки да, но хочется максимально упростить процесс.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

progman пишет:

asam пишет:

Подключаете ардуино к компу, а на компе генерерируете UUID и передаете ардуине для записи во флеш. Уникальность гарантируетчя.

Это таки да, но хочется максимально упростить процесс.

 

так написаиь прогу и все автоматом будет происходить

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

progman пишет:

но хочется максимально упростить процесс.

Если нужна гарантия уникальности, то это самое простое решение - дальше упрощать некуда.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Хорошая идея. При таком способе генерации повторения маловероятны. Энтропия неподключенного входа АЦП очень велика, а ты еще и несколько замеров собираешь...  все ОК.

Logik
Offline
Зарегистрирован: 05.08.2014

Взять замеров с АЦП сколько не жалко, от масива замеров посчитать хеш, любой какой приглянится. Он или его часть и будет ID.

AlexanderNO
Offline
Зарегистрирован: 08.11.2018

Генератор уникальных чисел можно получить из текущей даты и времени, а "случайные" числа - из времени (с секундами), например, через тригонометрические функции.  

Logik
Offline
Зарегистрирован: 05.08.2014

осталось дето время взять ;)

progman
Offline
Зарегистрирован: 26.01.2019

AlexanderNO пишет:

Генератор уникальных чисел можно получить из текущей даты и времени, а "случайные" числа - из времени (с секундами), например, через тригонометрические функции.  

вот только встроенных часов в arduino нет

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Подключил к компьютеру и получил свой номер, если до этого не было. 

AlexanderNO
Offline
Зарегистрирован: 08.11.2018

Можно к компьютеру, можно модуль часов для первого включения подкупить. 

b707
Offline
Зарегистрирован: 26.05.2017

wdrakula пишет:

Хорошая идея. При таком способе генерации повторения маловероятны. Энтропия неподключенного входа АЦП очень велика, а ты еще и несколько замеров собираешь...  все ОК.

Не верю я в "энтропию" аналогового входа.. А если он по грязи на плате будет замкнут на массу - будем получать все время числа в районе нуля.

progman
Offline
Зарегистрирован: 26.01.2019

AlexanderNO пишет:

Можно к компьютеру, можно модуль часов для первого включения подкупить. 

Если уж что то и подкупать то DS1990 - вско дешевле часов будет.

AlexanderNO
Offline
Зарегистрирован: 08.11.2018

Можно небольшой внешний EEPROM (типа 24С16) использовать для хранения счетчика порядкового номера. Подключать его при первом включении, считывать номер, добавлять единицу и записывать обратно. 

SLKH
Offline
Зарегистрирован: 17.08.2015

progman пишет:

SLKH пишет:

progman пишет:

 

Может быть уже есть готовые решения чтобы действительно уникальный ID сгенеритьи  прописать в память?

Есть секретный ресурс http://arduino.ru/forumy/programmirovanie , а на нем функция random() с готовым примером.

random - это псевдослучайный ГСЧ. секвенция "случайных" чисел будет одна и та же на всех устройствах.

а у analogRead слишком низкая энтропия - всего 10 бит

поэтому randomSeed(analogRead(0)); будет генерить одни и теже "случайные" числа на каждом из 1023 устройств.

риск что в одной партии сгенерится одинаковый серийный номер слишком велик

16 байт на уникальный номер - это ж сколько триллионов объем выпуска планируется?

 

 

SLKH
Offline
Зарегистрирован: 17.08.2015

запрограммировать вход с подтяжкой, коротнуть на землю и взять micros().

при паранойе - повторить несколько раз.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

SLKH пишет:

при паранойе - повторить несколько раз.

Боюсь, без нейролептиков и антипсихотиков это будет недостаточно эффективно :(

Green
Offline
Зарегистрирован: 01.10.2015

progman пишет:

вот только встроенных часов в arduino нет

__TIME__

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Если контроллеры не будут писаться пачками ежесекундно, то вариант "md5(__DATE__ + __TIME__)  -> EEPROM" представлятся неплохим вариантом. md5 можно на что-нить покороче заменить, наверняка. С другой стороны - зачем EEPROM, если эта строка будет генерироваться на старте... Разве что побыстрее стартанет МК. Да и то - замерять надо, что накладней выйдет.

P.S. да и хэш там для красоты, в принципе... повыкидывать со строки всё, что "не цифра" - всё равно получится нарастающая величина... 

P.P.S. Сорри, не учел, что __DATE__ выдает месяц словом и не подумал, что контроллеры могут шиться одной и той же компиленной прошивкой. Но, если перед каждой прошивкой будет перекомпиляция, то нашёл способ брать unix timestamp: https://stackoverflow.com/questions/23032002/c-c-how-to-get-integer-unix-timestamp-of-build-time-not-string - он то будет уникальным в пределах секунд.

Green
Offline
Зарегистрирован: 01.10.2015

UNIX time достаточно.)

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Green пишет:

UNIX time достаточно.)

Как оказалось - его не так просто отобрать у компилятора...

Green
Offline
Зарегистрирован: 01.10.2015

Отобрать __DATE__ __TIME__ , а самому перевести в свой "UNIX-time".

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ну, вот выше как раз ссылка на готовый стероидный юникстайм со стековерфлоу.