Jump to content
Hertz

Propriul cititor de benzi magnetice

Recommended Posts

Intotdeauna am fost interesat de cum si ce date sunt stocate pe banda magnetica a diferitor carduri, asa ca am decis sa creez un cititor din un vechi casetofon.

Hardware

Partea hardware pentru acest proiect e destul de simpla. Banda magnetica e citita folosind un cap magnetic de la un vechi mono casetofon si cateva componente pentru a amplifica semnalul in vederea citirii mai usoare. Acesta e conectat la mufa pentru microfon a PC-ului. Puterea pentru amplificator e de asemenea luata din inputul pentru microfon, notebook-ul meu outputeaza cam 3V acolo. Pentru mai multe detalii, uitate la schema amplificatorului de AICI

Poza cu cititorul :

http://i50.tinypic.com/21o29ax.jpg

Software

.

Prima oara am incercat softurile de AICI si de AICI , dar nicicare dintre acestea doua nu au fost prea stabile (pentru mine), asa ca m-am decis sa imi scriu propriul decoder. Inainte sa citesti mai departe iti recomand sa inveti despre cum sunt datele codate pe banda magnetica. Decoderul meu incearca prima oara sa masoare latimea pulsului bitilor initiali, apoi foloseste acea marime ca referinta pentru decodarile urmatoare.

Asta se face masurand grosimea tuturor pulsurilor urmatoare si comparandule cu ultimul puls cu grosimea zero. Daca doua grosimi sunt mai aproape de pulsul zero decat de primul puls, pulsurile sunt decodate ca 1. Altfel primul puls e interpretat ca 0. In final, pulsul zero este schimbat folosind un factor dat la ultimul puls masurat pentru a lucra cu viteze diferite de lovire.

Exemplu

Sa spunem ca decoderul detecteaza urmatoarele grosimi ale pulsurilor : 91, 101, 90, 55, 44, 51, 45, 98, 48, 49, 91, 101

1) Prima grosime (91) este folosita ca pulsul zero ( sa-l numim zp)

2) Apoi zp-ul este comparat cu urmatorul puls (101; |91-101| = 10) si suma urmatorilor 2 (101+90 = 191; |91-191| = 100)

3) Dupa cum se poate vedea, grosimea e mai aproape de zp (10<100) deci pulsul e decodat ca 0

4) In cele din urma valoarea lui zp este ajustata la noua grosime de puls folosind un factor definit f (am ales 0.2 aici, dupa cateva teste initiale)


zp_nou = zp - ((zp - grosime) * f)
zp_nou = 91-((91-101)*0.2)=93

5) Urmatorul puls e decodat tot ca acesta, deci nu voi explica din nou.


zp_nou = 93-((93-90)*0.2)=92 (rotunjit la cea mai mica valoare)

6) Apoi zp e comparat cu urmatoarea grosime (55; |92-55|=37) si suma urmatoarelor doua (55+44=99; |92-99|=7)

7) Acum suma urmatoarelor doua pulsuri e mai aproape de zp (7<37) deci cele doua pulsuri sunt decodate ca 1

8)

 zp_nou=92-((92-(55+44))*0.2)=93 

9) Acum totul continua ca inainte exceptand faptul ca trebuie sa folosesti 51 si 45 in loc de 44 si 51 (trebuie sa avansezi cu 2 numere in vector).

Folosire

Trebuie sa ai sox pentru a functiona.

Decodeaza un fisier .wav inregistrat - track 1

  sox fisier.wav -r 48000 -t dat -q - | ./bifaze.pl 1 

Decodeaza un fisier live - track 2

 sox rec -r 48000 -t dat -q - | ./bifaze.pl 2 

Sursa decoderului meu - bifaze.pl


#!/usr/bin/perl -w

# Written by Hertz <ownage [dot] hertz [at] gmail.com>

use strict;

my $track = 2;
$track = 1 if((scalar(@ARGV) == 1) && ($ARGV[0] eq '1'));

my $threshold_1 = 0.2;
my $maxlen_1 = 150;
my $adoptrate_1 = 0.2;
my $smalldiff_1 = 0.1;

my $threshold_2 = 0.2;
my $maxlen_2 = 350;
my $adoptrate_2 = 0.2;
my $smalldiff_2 = 0.1;

my $dbg_lens = 0;
my $dbg_dec = 0;

###############################################################################

my $chars_1 = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';
my $charlen_1 = 6;

my $chars_2 = '0123456789:;<=>?';
my $charlen_2 = 4;

###############################################################################

$| = 1;

my $threshold = $threshold_1;
my $maxlen = $maxlen_1;
my $adoptrate = $adoptrate_1;
my $smalldiff = $smalldiff_1;
my $chars = $chars_1;
my $charlen = $charlen_1;

if($track == 2) {
$threshold = $threshold_2;
$maxlen = $maxlen_2;
$adoptrate = $adoptrate_2;
$smalldiff = $smalldiff_2;
$chars = $chars_2;
$charlen = $charlen_2;
}

my $slope = 1;
my $old = 0;
my $data = 0;
my $olddata = 0;
my $init = 1;
my $mode = 0;
my $count = 0;
my $len = 0;
my $curlen = 0;
my $oldlen = 0;
my $bitmode = 0;
my $chk = 0;
my $complete = 1;

my $celllen = 0;
my $str = '';

sub parity_ok
{
my $charlen = shift;
my $c = shift;

my $one = 0;
for(my $j = $charlen - 1;$j >= 0;$j--) {
$one++ if(substr($c, $j, 1) eq '1');
}
$one++ if(substr($c, $charlen, 1) eq '1');

return ($one % 2) == 1;
}

sub xtract_char
{
my $charlen = shift;
my $c = shift;

my $x = 0;
for(my $j = $charlen - 1;$j >= 0;$j--) {
$x <<= 1;
$x |= 1 if(substr($c, $j, 1) eq '1');
}

return $x;
}

sub decode_char
{
my $charlen = shift;
my $chars = shift;
my $str = shift;

return ('x', 0) if(!parity_ok($charlen, $str));

my $x = xtract_char($charlen, $str);

return ('y', 0) if($x >= length($chars));

return (substr($chars, $x, 1), $x);
}

while(<STDIN>) {
chop;
next if(/^;/);
next unless(/([+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?) +([+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?)/);

my ($t, $y) = ($1, $2);

my $s = $slope;
if($y > $threshold) {
$s = 1;
} elsif($y < (-1 * $threshold)) {
$s = -1;
}

if($slope != $s) {
$slope = $s;
if($data) {
$data = 0;
} else {
$data = 1;
}
}

if($init) {
$len = 0;
$olddata = $data;
$init = 0;
$mode = 0;
$bitmode = 0;
} else {
my $lenchange = 0;
my $gotbit = 0;

if($len > $maxlen) {
$mode = 0;
$bitmode = 0;
$init = 1;
if(!$complete) {
print " TIMEOUT\n";
$complete = 1;
}
} else {
if($olddata != $data) {
print "$len\n" if($dbg_lens);
$oldlen = $len;
$curlen = $len;
$len = 0;
$lenchange = 1;
} else {
$len++;
}
}

if($lenchange) {
if($mode == 0) {
$count = 3;
$mode++;
} elsif($mode == 1) {
if($count <= 0) {
$str = '';
$mode++;
} else {
$count--;
}
} elsif($mode == 2) {
my $c = $oldlen;
my $n = $curlen;

my $d0 = abs($celllen - $c);
my $d1 = abs($celllen - ($c + $n));

my $d = 0;

print abs($d0 - $d1) . " " . ($celllen * $smalldiff) . "\n" if($dbg_dec);
if(abs($d0 - $d1) > ($celllen * $smalldiff)) {
if($d0 < $d1) {
$d = 0;
} else {
$d = 1;
}
} else {
$d = 1;
}

$str .= $d;
$gotbit = 1;
print "$c $n $d0 $d1 $celllen $d\n" if($dbg_dec);
if($d == 0) {
$celllen -= int(($celllen - $c) * $adoptrate);
} else {
$celllen -= int(($celllen - ($c + $n)) * $adoptrate);
$mode++
}
print "-> $celllen\n" if($dbg_dec);
} elsif($mode == 3) {
$mode--;
}
}

if($gotbit) {
if($bitmode == 0) {
$complete = 0;
if($str eq '1') {
$bitmode++;
$chk = 0;
} else {
$str = '';
}
} elsif($bitmode == 1) {
if(length($str) >= ($charlen + 1)) {
my $c = substr($str, 0, $charlen + 1);
$str = substr($str, $charlen + 1);

print "p" if(!parity_ok($charlen, $c));

my ($ch, $x) = decode_char($charlen, $chars, $c);
$chk ^= $x;
print "$ch";

$bitmode++ if($ch eq '?');
}
} elsif($bitmode == 2) {
if(length($str) >= ($charlen + 1)) {
my $c = substr($str, 0, $charlen + 1);
$str = substr($str, $charlen + 1);

print "p" if(!parity_ok($charlen, $c));

my ($ch, $x) = decode_char($charlen, $chars, $c);
$chk ^= $x;

if($chk) {
print " ERROR\n";
} else {
print " OK\n";
}
$complete = 1;

$bitmode = 0;
}
}
}
}

$olddata = $data;
$old = $y;
}

  • Upvote 4
  • Downvote 4
Link to comment
Share on other sites

si acum o intrebare de n00bie...oare se poate si inversa procesul cumva folosind tot acelasi vechi casetofon (ma refer la inscriptionarea benzii)? Banuiesc ca da. Poate faci un tutorial si pe tema asta. Ma apuc sa fac si eu aceeasi chestie pe baza tut. tau

Bafta in continuare!

PS: nu vreau sa gasesc ceva "home made" care sa inlocuiasca msr'ul, doar asa ca si cultura generala

Link to comment
Share on other sites

ideea este buna. dar cam incomplecta. si aici ma refer la componentele care compun "miau-miau" :)) cred ca a fost putin plagiatura, dar daca cumva ma insel si nu e asa, rog a se da detalii despre piese: marimea capului, cate track-uri citeste, ce fel de acumulatori s-a folosit, memoria este interna(proprie capului de citire) sau externa ? ce fel de memorie s-a folosit ?

se vorbea despre descarcarea datelor criptate. ce fel de piciorush(OUT) s-a folosit ?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...