Вводная
Время не стоит на месте — оно течет и изменяется. Технический прогресс диктует свои правила жизни. Одно из этих правил — наличие важнейшего инструмента повседневности — пластиковой карточки. Кредитные, расчетные, депозитные, карточки-визитки, клубные, карточки постоянных покупателей — теперь без них не обходится ни одно цивилизованное общество. Но что делать, если этих «общепризнанных инструментов жизнедеятельности человека» становится слишком много? Что если от их избытка ваш любимый кошелек начинает трещать по швам? Сегодня мы поговорим о том, как данной проблемы можно избежать. А именно, как несколько карточек превратить… в одну.
Немного теории
Как же хранится информация? Да очень просто. По сути, магнитная полоса — это последовательность маленьких участков, намагниченных в противоположных направлениях. На месте перехода между участками напряженность магнитного поля резко меняется. Именно это изменение магнитного поля фиксирует магнитная головка, которая скользит по полосе, когда вы проводите карточку. За счет резкого изменения магнитного поля в катушке головки возникает ЭДС (электродвижущая сила), проще говоря, появляется импульс напряжения, который затем усиливается и передается дальше.
Для различия нулей и единиц используется так называемое F/2F кодирование: то есть при кодировании нуля используется частота F, а для единицы — частота 2F. Например, в начале дорожки у нас идет несколько нулей, служащих для синхронизации, тогда декодирующее устройство примерно вычисляет частоту F (в частности время одного полупериода равного Т), и если же импульс возникал по истечению времени Т, то мы имеем дело с нулем, если посередине этого времени и в конце (удвоенная частота), то это логическая единица.
Этот метод построен на принципе того, что мы не сможем моментально изменить скорость провода карточкой в 1.5 раза. Благодаря тому, что у нас присутствует импульс в конце каждого бита, мы можем корректировать время Т без опасения плавного изменения скорости. В противном случае это грозит сбоем синхронизации.
На каждой карточке с магнитной полосой всегда имеется 3 трека. Другое дело, что они не всегда используются.
1й трек | формат ALPHA | 79 символов | 7 бит на символ | плотность записи 210 бит на дюйм |
2й трек | формат BCD | 40 символов | 5 бит на символ | плотность записи 75 бит на дюйм |
3й трек | формат BCD | 107 символов | 5 бит на символ | плотность записи 210 бит на дюйм |
В случае дисконтных карт чаще всего используется только вторая дорожка, по причине того, что на ней самая маленькая плотность записи, и, как следствие, самая большая устойчивость к помехам в виде прилипших субстанций, царапин или даже трещин. Обычно там записан числовой идентификатор носителя карты, он же на всякий случай продублирован на лицевой части самой карты.
В случае банковских карт используется первая и вторая дорожки. Смысл данных известен только самим банкам.
3-я дорожка в подавляющем количестве случаев не используется.
Физическая ширина информационной дорожки составляет 2.8 мм.
b1 | b2 | b3 | b4 | b5 | Character | Function | |
---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 0 | (0H) | Data |
1 | 0 | 0 | 0 | 0 | 1 | (1H) | " |
0 | 1 | 0 | 0 | 0 | 2 | (2H) | " |
1 | 1 | 0 | 0 | 1 | 3 | (3H) | " |
0 | 0 | 1 | 0 | 0 | 4 | (4H) | " |
1 | 0 | 1 | 0 | 1 | 5 | (5H) | " |
0 | 1 | 1 | 0 | 1 | 6 | (6H) | " |
1 | 1 | 1 | 0 | 0 | 7 | (7H) | " |
0 | 0 | 0 | 1 | 0 | 8 | (8H) | " |
1 | 0 | 0 | 1 | 1 | 9 | (9H) | " |
0 | 1 | 0 | 1 | 1 | : | (AH) | Control |
1 | 1 | 0 | 1 | 0 | ; | (BH) | Start Sentinel |
0 | 0 | 1 | 1 | 1 | < | (CH) | Control |
1 | 0 | 1 | 1 | 0 | = | (DH) | Field Separator |
0 | 1 | 1 | 1 | 0 | > | (EH) | Control |
1 | 1 | 1 | 1 | 1 | ? | (FH) | End Sentinel |
5-й бит выступает в роли бита паритета.
В формате кодирования альфа (там, где 7 бит на символ) есть возможность хранить цифры, латинские буквы и немного спецсимволов.
b1 | b2 | b3 | b4 | b5 | b6 | b7 | Character | Function | |
---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 1 | space | (0H) | Special |
1 | 0 | 0 | 0 | 0 | 0 | 0 | ! | (1H) | " |
0 | 1 | 0 | 0 | 0 | 0 | 0 | " | (2H) | " |
1 | 1 | 0 | 0 | 0 | 0 | 1 | # | (3H) | " |
0 | 0 | 1 | 0 | 0 | 0 | 0 | $ | (4H) | " |
1 | 0 | 1 | 0 | 0 | 0 | 1 | % | (5H) | Start Sentinel |
0 | 1 | 1 | 0 | 0 | 0 | 1 | & | (6H) | Special |
1 | 1 | 1 | 0 | 0 | 0 | 0 | ' | (7H) | " |
0 | 0 | 0 | 1 | 0 | 0 | 0 | ( | (8H) | " |
1 | 0 | 0 | 1 | 0 | 0 | 1 | ) | (9H) | " |
0 | 1 | 0 | 1 | 0 | 0 | 1 | * | (AH) | " |
1 | 1 | 0 | 1 | 0 | 0 | 0 | + | (BH) | " |
0 | 0 | 1 | 1 | 0 | 0 | 1 | , | (CH) | " |
1 | 0 | 1 | 1 | 0 | 0 | 0 | — | (DH) | " |
0 | 1 | 1 | 1 | 0 | 0 | 0 | . | (EH) | " |
1 | 1 | 1 | 1 | 0 | 0 | 1 | / | (FH) | " |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | (10H) | Data (numeric) |
1 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | (11H) | " |
0 | 1 | 0 | 0 | 1 | 0 | 1 | 2 | (12H) | " |
1 | 1 | 0 | 0 | 1 | 0 | 0 | 3 | (13H) | " |
0 | 0 | 1 | 0 | 1 | 0 | 1 | 4 | (14H) | " |
1 | 0 | 1 | 0 | 1 | 0 | 0 | 5 | (15H) | " |
0 | 1 | 1 | 0 | 1 | 0 | 0 | 6 | (16H) | " |
1 | 1 | 1 | 0 | 1 | 0 | 1 | 7 | (17H) | " |
0 | 0 | 0 | 1 | 1 | 0 | 1 | 8 | (18H) | " |
1 | 0 | 0 | 1 | 1 | 0 | 0 | 9 | (19H) | " |
0 | 1 | 0 | 1 | 1 | 0 | 0 | : | (1AH) | Special |
1 | 1 | 0 | 1 | 1 | 0 | 1 | ; | (1BH) | " |
0 | 0 | 1 | 1 | 1 | 0 | 0 | < | (1CH) | " |
1 | 0 | 1 | 1 | 1 | 0 | 1 | = | (1DH) | " |
0 | 1 | 1 | 1 | 1 | 0 | 1 | > | (1EH) | " |
1 | 1 | 1 | 1 | 1 | 0 | 0 | ? | (1FH) | End Sentinel |
0 | 0 | 0 | 0 | 0 | 1 | 0 | @ | (20H) | Special |
1 | 0 | 0 | 0 | 0 | 1 | 1 | A | (21H) | Data (alpha) |
0 | 1 | 0 | 0 | 0 | 1 | 1 | B | (22H) | " |
1 | 1 | 0 | 0 | 0 | 1 | 0 | C | (23H) | " |
0 | 0 | 1 | 0 | 0 | 1 | 1 | D | (24H) | " |
1 | 0 | 1 | 0 | 0 | 1 | 0 | E | (25H) | " |
0 | 1 | 1 | 0 | 0 | 1 | 0 | F | (26H) | " |
1 | 1 | 1 | 0 | 0 | 1 | 1 | G | (27H) | " |
0 | 0 | 0 | 1 | 0 | 1 | 1 | H | (28H) | " |
1 | 0 | 0 | 1 | 0 | 1 | 0 | I | (29H) | " |
0 | 1 | 0 | 1 | 0 | 1 | 0 | J | (2AH) | " |
1 | 1 | 0 | 1 | 0 | 1 | 1 | K | (2BH) | " |
0 | 0 | 1 | 1 | 0 | 1 | 0 | L | (2CH) | " |
1 | 0 | 1 | 1 | 0 | 1 | 1 | M | (2DH) | " |
0 | 1 | 1 | 1 | 0 | 1 | 1 | N | (2EH) | " |
1 | 1 | 1 | 1 | 0 | 1 | 0 | O | (2FH) | " |
0 | 0 | 0 | 0 | 1 | 1 | 1 | P | (30H) | " |
1 | 0 | 0 | 0 | 1 | 1 | 0 | Q | (31H) | " |
0 | 1 | 0 | 0 | 1 | 1 | 0 | R | (32H) | " |
1 | 1 | 0 | 0 | 1 | 1 | 1 | S | (33H) | " |
0 | 0 | 1 | 0 | 1 | 1 | 0 | T | (34H) | " |
1 | 0 | 1 | 0 | 1 | 1 | 1 | U | (35H) | " |
0 | 1 | 1 | 0 | 1 | 1 | 1 | V | (36H) | " |
1 | 1 | 1 | 0 | 1 | 1 | 0 | W | (37H) | " |
0 | 0 | 0 | 1 | 1 | 1 | 0 | X | (38H) | " |
1 | 0 | 0 | 1 | 1 | 1 | 1 | Y | (39H) | " |
0 | 1 | 0 | 1 | 1 | 1 | 1 | Z | (3AH) | " |
1 | 1 | 0 | 1 | 1 | 1 | 0 | [ | (3BH) | Special |
0 | 0 | 1 | 1 | 1 | 1 | 1 | ( | 3DH) Special | |
1 | 0 | 1 | 1 | 1 | 1 | 0 | ] | (3EH) | Special |
0 | 1 | 1 | 1 | 1 | 1 | 0 | ^ | (3FH) | Field Separator |
1 | 1 | 1 | 1 | 1 | 1 | 1 | _ | (40H) | Special |
7-й бит выступает в качестве бита паритета.
Информация на 2-й или 3-й дорожке хранится в следующей последовательности:
- Некоторое количество нулевых бит, около 20;
- Символ начала данных «;»;
- число, или несколько чисел разделенных между собой символом «=»;
- признак конца данных «?»;
- LRC (Longitudinal Redundancy Check) — для проверки всего сообщения;
- Некоторое количество нулевых бит, около 20;
Первая дорожка содержит аналогичную последовательность за исключением символа начала данных «%».
К практике
Для того, чтобы имитировать магнитную полосу во время провода карточкой, необходимо генерировать изменение магнитного поля вблизи считывающей головки. Для этого подойдет простая катушка, на которую будет подаваться специально промодулированный сигнал. Для того, чтобы наш имитатор карточки можно было протягивать, необходимо катушку разместить на протяжении всей карточки. Также неплохо, чтобы направление намагниченности совпадало с направлением на карточке. Тут нам повезло: он проходит вдоль длинного края карточки и будет достаточно однослойной катушки длинной примерно с карточку. Для усиления намагниченности в качестве сердечника будем использовать магнитомягкий ферромагнетик из электрической стали (сердечника трансформатора). Форма сердечника — прямоугольная; плоской стороной прилегает к считывающей головке, что делает их взаимосвязь более сильной.
В процессе намотки нам поможет шуруповерт. Также желательно покрыть перед этим сердечник лаком, чтобы исключить возможность короткого замыкания витков через сердечник, иначе область катушки в пространствах между замкнутыми витками не эффективна.
Для удобства считывания упакуем нашу катушку в «корпус», сходный с формой стандартной пластиковой карточкой.
Обмотаем скотчем.
Теперь задумаемся о том, как будем подавать на катушку сигнал. Для этого нам понадобится драйвер. Так как выходной мощности портов GPIO контроллера нам не хватит, воспользуемся схемой типа Н-мост.
MS1 и MS2 подключаем к портам контроллера, выход Р1 — на катушку.
Конденсаторы С43 и С44 служат в качестве фильтров для снятия постоянной составляющей с катушки. Это позволяет сэкономить заряд батареи, а также управлять крутизной фронтов импульса, что в свою очередь положительно влияет на магнитное взаимодействие катушки и магнитной головки (величина ЭДС прямпропорциональна скорости изменения магнитного поля).
Установим фильтр, чтобы избавить остальную часть схемы от бросков по питанию.
Для генерации импульсов на выходе головки нам нужно на выходы катушки подавать импульсы в противофазе. Для этого одновременно меняем логические уровни на MS1 и MS2 на противоположные, благодаря чему на выходы катушки кратковременно будет приложено удвоенное значение напряжения VMS. Другой способ — использовать только одно плечо H-моста с одной стороны катушки и среднюю точку на другом.
Контроллер для управления схемой взят с запасом вычислительной мощности — STM32F405.
Итак, код на примере второй дорожки:
//инициализация порта:
#define STRIPE_2_PIN_P GPIO_Pin_13
#define STRIPE_2_PIN_N GPIO_Pin_14
#define STRIPE_2_PORT GPIOB
#define STRIPE_2_RCC_PERIPH RCC_AHB1Periph_GPIOB
void stripe_init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(STRIPE_2_RCC_PERIPH, ENABLE);
GPIO_SetBits(STRIPE_2_PORT, STRIPE_2_PIN_P);
GPIO_ResetBits(STRIPE_2_PORT, STRIPE_2_PIN_N);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = STRIPE_2_PIN_P | STRIPE_2_PIN_N;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(STRIPE_2_PORT, &GPIO_InitStructure);
}
//генерация одного импульса:
void stripe_2_toggle(void) {
GPIO_ToggleBits(STRIPE_2_PORT, STRIPE_2_PIN_P | STRIPE_2_PIN_N);
}
//передача логического нуля:
void stripe_2_tx_0 (void) {
stripe_2_toggle();
vait_stripe_2_period();
}
//передача логической единицы:
void stripe_2_tx_1 (void) {
stripe_2_toggle();
vait_stripe_2_half_period();
stripe_2_toggle();
vait_stripe_2_half_period();
}
Функции для передачи битов готовы.
Более продвинутый уровень — преобразовать информацию в последовательность нулей и единиц и начинать их поочередную передачу (если же преобразовывать каждый символ в момент передачи это сулит сдвижки по времени и нарушением синхронизации приемной части). Но мы пренебрежем этим для простоты исполнения.
//отправка сообщения
void buff_2_to_magnetic(char * stripe_2_buff) {
unsigned char i, lrc = 0;
for (i = 0; i < 20; i++) {
stripe_2_tx_0();
}
while (*stripe_2_buff) {
for (i = 0; i < 5; i++) {
if (*stripe_2_buff & (1 << i)) {
stripe_2_tx_1();
} else {
stripe_2_tx_0();
}
}
lrc ^= *stripe_2_buff;
stripe_2_buff++;
}
for (i = 0; i < 5; i++) {
if (lrc & (1 << i)) {
stripe_2_tx_1();
} else {
stripe_2_tx_0();
}
}
}
В случае, если вы планируете одновременно эмулировать две или более полосы, следует учесть, что из-за разной плотности записи на дорожках между импульсами возникают различные временные промежутки, для измерения которых потребуется соответственное количество измерителей времени. Например, можно воспользоваться таймерами или «таском» в операционной системе.
Исследовательская часть
- В основном успешность затеи зависит от следующих факторов:
- Напряжение VMS;
- Количества витков катушки;
- Диаметр провода в катушке;
- Поперечное сечение сердечника;
- Емкость конденсаторов С43 и С44;
- Частота F;
- Расстояние катушки от считывающей головки;
- Магнитная проницаемость сердечника.
Стоит учесть, что некоторые параметры изменяемы в конкретных пределах, некоторые — зависимы друг от друга.
К примеру, давайте подадим различное напряжение на катушку и выясним, как будет его изменение влиять на результат при учете неизменности остальных параметров:
Напряжение В | Расстояние срабатывания мм | Расстояние воздействия мм | Неравномерность считывания % | Неравномерность воздействия % |
---|---|---|---|---|
2.3 | 0 | 0 | 10% с концов | 15% с концов |
2.6 | 0 | 1 | 30% с концов | 70% с концов |
2.8 | 0 | 2 | 70% | 30% |
2.9 | 1 | 5 | 100% | 0% |
3 | 2 | 7 | 100% | 0% |
3.3 | 4 | 11 | 100% | 0% |
Расстояние срабатывания – максимальное расстояние, при котором происходит успешное считывание (0 при непосредственном прикосновении).
Расстояние воздействия – расстояние, при котором чтение производится, но с ошибкой.
Неравномерность считывания – в связи с тем, что магнитный сердечник не замкнут, на его концах более сильное магнитное поле.
По составленной таблице видно, что лучший результат приходится на диапазон напряжения 2.8-2.9 В.
2.6 В:
2.8 В:
2.9 В:
3 В:
3.3 В:
Выводы
В процессе работы два недостатка:
- Влияние сигнала предыдущей дорожки на соседнюю;
- Неравномерная интенсивность магнитного поля вдоль катушки. Проявляется особенно сильно при протаскивании карточки в отличие от ее неподвижного состояния.
В первом случае может помочь использование дополнительных экранов, или схематическое решение в виде подачи ослабленного сигнала на соседнюю катушку в инверсном подключении. Таким образом, сигнал и помеха будут в противофазе и погасят друг друга. Также дополнительную помощь оказывает замыкание магнитного контура.
Во втором случае может помочь замкнутость магнитного контура, а также плавное изменение площади сечения сердечника ближе к концам катушки.
Видео работы устройства:
GitHub
Комментарии (21)
engine9
06.04.2015 13:18+1А почему именно такая намотка, а не плоская катушка? Ведь силовые линии будут выходить из торцов, а нужно в плоскости.
tachcard Автор
06.04.2015 14:38+2магнитная головка считывателя магнитных карт (также как в касетниках/бобинниках) рассчитана на продольную намагниченность, в противном случае пришлось бы делать магнитопровод от обратной стороны карточки обратно в головку.
Sergey-S-Kovalev
06.04.2015 13:52+2Штрихкодовые карты фотографирую, продавцы косятся, но в большинстве случаев принимают такой вариант «клубной карты». Избавился от необходимости таскания с собой кучи карт, хотя несколько приходится собой всеравно брать. На всякий случай.
Из прокси карты вытащил магнитную таблетку — затолкал под заднюю крышку телефона, открываю телефоном двери от подъезда дома/работы. Минус брелок на ключах.
А вот NFC увы не востребован в моих реалиях.tachcard Автор
06.04.2015 14:44+3Кстати лазерным сканером штрих кодов не всегда удается считать с экрана телефона, но хорошо считывается с экранов на основе электронных чернил
vk2
06.04.2015 15:39Вам сюда: dangerousthings.com — вживление nfc-чипа в руку
Sergey-S-Kovalev
06.04.2015 16:14Из вещей, которые я добровольно готов принять в свой организм на постоянной основе, я согласен только на пломбы.
hopungo
07.04.2015 10:51Всё-таки не понял, как эта технология позволит «превратить несколько карт в одну». Судя по статье, вы сделали комплект для записи пластиковых карт на коленке. Неужто пользователь будет ходить с чемоданчиком, программируя карточку перед каждой операцией считывания?
tachcard Автор
07.04.2015 11:35+1Тут освещен только процесс имитации работы магнитной полосы, победив это ничего не мешает запрограммировать формацию сразу с нескольких карточек и переключаться кнопками, или к примеру синхронизироваться по bluetooth c телефоном и добавлять/выбирать текущую карточку с него, + существуют кардридеры для телефонов. К слову связь с телефоном уже реализована средствами Bluetooth LE
hopungo
07.04.2015 12:22+1Да, про кардридеры для телефонов я слышал. Мне понравился тот, который вставляется в гнездо для наушников. Однако, задача, поставленная вами, весьма нетривиальна. Я бы по возможности постарался избавить пользователя от ручного переключения карты, хотя без изменения считывающего устройства это вряд ли реализуемо в принципе. А вероятность
резистатого, что во всех магазинах тут же поменяют терминалы под универсальные карточки, крайне мала. На мой взгляд, всё-таки проще пользоваться QR-кодами.tachcard Автор
07.04.2015 13:13Считывающие устройства менять ненужно. Даже наличие кнопок переключения (аккумулятора, блютуз модуля) на это не
влияет.hopungo
07.04.2015 14:13+1Хорошая штука, но до мультипаспорта не дотягивает. Что-то подсказывает мне, что всё равно придётся таскать с собой ворох карточек, ибо некоторые будут поддерживать только платежи в фиатной валюте, в некоторых сядет аккумулятор, а другие принципиально будут отвергаться ввиду конкуренции различных фирм.
На мой взгляд, кнопки переключения на самих картах — зло. Как и зависимость работоспособности карты от мобильного телефона. Я бы предпочёл карту, которой расплачиваешься один раз, и магазин автоматически заводит тебе персональный дисконтный счёт. Конечно, при согласии владельца, но вряд ли кто от этого откажется.Sergey-S-Kovalev
07.04.2015 17:34Были же статьи про универсальную карту в Китае. В ней все. И идентификация, и медицина, дисконты. Вот он, почти, философский камень.
blezalex
07.04.2015 19:31+1Интересно, а получилось бы через порт наушников (микрофона) записать дорожку в телефон, а потом через порт через этот-же порт проиграть на такую карточку?
tachcard Автор
08.04.2015 12:47Самые простые считыватели для телефон так и работают, головка напрямую подключается к микрофону и ПО пытается по полученному сигналу расшифровать данные, как правило удачно распознается не больше половины считываний (проводов карточкой). Передать конечно тоже можно, промодулировать полученные данные и передать, а на стороне карточки распознать, но по мне лучше использовать Bluetooth. Идеально было бы считыватель организовать прямо на карточке, но у нас не получилось сделать его достаточно компактным.
Cobolorum
А не ушел ли паровоз данной технологии?
Scratch
Буквально пару недель назад анонсировали Galaxy S6, в котором будет www.looppay.com/
tachcard Автор
возможно это и стало причиной появления этой статьи.