非安定マルチバイブレータ回路でLEDを点滅させてみる

電子工作の練習として、簡単な回路を作ってみる。

部品調達

必要な部品がセットになった商品があるので、これを利用する。 また、この商品はスズメッキ線を切って繋ぐようになっているが、いちいちワイヤを切るのも面倒なのでジャンパワイヤセットを用意した。 ニッパーやピンセットは100円均一のもので十分である。

回路図

このセットの回路図は次のようになっている(取扱説明書より引用)。

f:id:inaz2:20160822205104p:plain

LEDの点灯時間の理論値は ln(2) * R * C = ln(2) * 47kΩ * 47uF = 1.53 sec となる。

次のページで、回路シミュレータによる動作のイメージを見ることができる。

LEDを点滅させてみる

ブレッドボード上に回路を組み立て、電池に繋いでみると、次の動画のようになる。

片方のLEDを3Vで動作する電子ブザーPB04-SE12HPRに変えてみると、次の動画のようになる。

関連リンク

GNU RadioでFMラジオ受信機を作ってみる

「Raspberry PiとUSBチューナー(RTL2832U+R820T)でFMラジオを受信してみる」では、市販のUSBチューナーを使ってFMラジオを受信してみた。 ここでは、SDR(Software-defined Radio)ツールであるGNU Radioを使ってFMラジオ受信機を作ってみる。

環境

Windows 10 Pro 64 bit版、Intel® Core™ i5-4200U Processor (3M Cache, up to 2.60 GHz)

>systeminfo
OS 名:                  Microsoft Windows 10 Pro
OS バージョン:          10.0.10586 N/A ビルド 10586
OS ビルドの種類:        Multiprocessor Free
システムの種類:         x64-based PC
プロセッサ:             1 プロセッサインストール済みです。
                        [01]: Intel64 Family 6 Model 69 Stepping 1 GenuineIntel ~1596 Mhz

GNU Radioのインストール

GNU Radioは、用意された変調・復調や周波数フィルタを行うブロックを組み合わせることで、柔軟にデジタル信号処理を行うことができるソフトウェアである。 ここでは、Windows上にGNU Radioをインストールし、RTL2832U+R820Tで受信した信号をTCP経由で受け取り処理することを考える。

まず、64 bit Windows版のダウンロードページから「Windows Installer」をダウンロードする。 ここでは利用するCore i5-4200UプロセッサがHaswellアーキテクチャであることから、「64-bit HASWELL+ (AVX2) CPU」版をダウンロードした。

インストーラを起動し既定の設定でインストールを行うと、スタートメニューの「すべてのアプリ」に「GNU Radio」フォルダが作成される。 この中の「GNURadio Companion」を実行すると、次のスクリーンショットのようなGUIアプリケーションが起動する。

f:id:inaz2:20160806003215p:plain

FMラジオ受信機を作成する

右のメニューからブロックを選択し、FMラジオ受信機を作成すると次のようになる。

f:id:inaz2:20160806003228p:plain

GNU Radioで作成したダイアグラムは拡張子grcのXMLファイルとして保存できる。 上のgrcファイルを次に示す。

この受信機の構成を簡単に説明すると次のようになる。

  1. RTL-SDR Source: TCP経由でI/Q信号を受信する(受信周波数80.0 MHz、サンプリングレート1200000 samples/sec、RF Gain 40 db)
  2. Low Pass Filter: ダウンサンプリングの前にナイキスト周波数を越える高周波をカットする(カットオフ周波数100 KHz、トランジション幅10 KHz)
  3. Rational Resampler: ダウンサンプリングを行う(サンプリングレート200 KHz)
  4. WBFM Receive: Wideband FMの復調を行い、48 KHzのPCM音声に変換(直交レート192 KHz、音声デシメーション1/4)
  5. FM Deemphasis: デエンファシスを行う(時定数50μs)
  6. Multiply Const: 音量調整を行う(5倍)
  7. Audio Sink: 音声を出力する(サンプリングレート48 KHz)

なお、スクリーンショットの左側にあるいくつかのパラメータは変数として定義している。 また、各ブロックについている端点の色はデータ型を表し、水色は複素数、オレンジ色は浮動小数点数を意味する。

Run→Execute(F6キー)を選択すると、次のスクリーンショットのようなウィンドウが表示され、FMラジオ(TOKYO FM 80.0 MHz)の音声が流れることが確認できる。

f:id:inaz2:20160806003245p:plain

関連リンク

大手サービスの行動履歴データの扱いについてまとめてみる

GoogleFacebookなどのWebサービスAdWords、DoubleClickなどの広告ネットワークは、ユーザのアクセス履歴や訪問サイト・検索ワード等を収集し、サービスのパーソナライズや広告表示に利用していることが知られている。 ここでは、そのような行動履歴データの取り扱いポリシーとサービスへの適用可否の設定方法についてまとめてみる。

Google

Googleが収集しているデータについては次に説明がある。

アカウントに関連付けられたデータの一部は次から確認できる。

サービスへの適用可否については、次のページから設定できる。

また、GoogleYouTubeGoogle AnalyticsAdWords、AdMob、DoubleClickと互いにデータを共有しており、収集されたデータは広告表示に適用される。 広告表示への適用可否については、次のページから設定できる。

Facebook

Facebookが収集しているデータについては次に説明がある。

アカウントに関連付けられた広告属性は次のページから確認できる。

広告表示への適用可否については、次のページから設定できる。

Twitter

Twitterが収集しているデータについては次に説明がある。

アカウントに関連付けられたデータの一部は次から確認できる。

サービスへの適用可否については、次のページから設定できる。

Amazon.co.jp

Amazonが収集しているデータについては次に説明がある。

アカウントに関連付けられた閲覧履歴は次から確認できる。

広告表示への適用可否については、次のページから設定できる。

補足

行動履歴データの収集と利用はサービスや広告配信の品質向上に活用されている一方、プライバシー侵害への懸念もあり、各社がプライバシーポリシーを表明し運用している現状にある。 また、このようなデータ収集はログインしていない際にも行われている可能性が極めて高く、ログイン後のアカウント情報と結び付けられる危険性がある。 広告サービスを提供する企業のうち、Network Advertising Initiativeに加盟している企業については、次のページから広告における行動履歴データの利用をオプトアウトすることができるが、「オプトアウトを表明した」という記録が行われることに注意が必要である。

ユーザ側での対策としては、ブラウザにおけるプライベートブラウジングモードの利用、サードパーティーCookieの拒否、NoScriptによるクロスオリジンリソースの制限、AdBlockや/etc/hostsによるドメインブラックリストの利用が考えられる。 ただし、このような対策を行った上でも、IPアドレスとアクセス時刻の組の収集によりある程度の個人特定が可能である。 また、近年ではBrowser Fingerprintと呼ばれる環境情報の収集により、高い精度で個人特定が可能であることが報告されている。

関連リンク

Raspberry PiとUSBチューナー(RTL2832U+R820T)でFMラジオを受信してみる

Raspberry Piに市販のUSBチューナーを接続して、FMラジオを受信してみる。 また、受信している電波の周波数スペクトルを表示してみる。

環境

Raspberry Pi 3 (Raspbian Jessie Lite)

$ uname -a
Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l GNU/Linux

$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

USBチューナーを用意する

ここでは、USBチューナーとしてRTL2832U+R820Tを利用する。 このチューナーで受信できる周波数レンジは24-1766MHzである。

Raspberry PiのUSBポートに接続し、デバイスが認識されていることを確認する。

$ lsusb
Bus 001 Device 008: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T

RTL-SDRのインストール

RTL2832Uに対応したSDR(Software-defined Radio)ツールであるRTL-SDRをインストールする。

$ sudo apt-get install rtl-sdr

テストコマンドを実行するとカーネルドライバと競合している旨のエラーが表示されるので、該当するカーネルモジュールをブラックリストに指定し再起動する。

$ sudo rtl_test
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM

Kernel driver is active, or device is claimed by second instance of librtlsdr.
In the first case, please either detach or blacklist the kernel module
(dvb_usb_rtl28xxu), or enable automatic detaching at compile time.

usb_claim_interface error -6
Failed to open rtlsdr device #0.
$ sudo vi /etc/modprobe.d/rtlsdr-blacklist.conf
blacklist dvb_usb_rtl28xxu

$ sudo reboot

改めてテストコマンドを実行すると、正常に動作していることを確認できる。

$ sudo rtl_test
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...
^CSignal caught, exiting!

User cancel, exiting...
Samples per million lost (minimum): 0

FMラジオを受信してみる

RTL-SDRにはFM復調を行うrtl_fmコマンドが同梱されている。 例としてTOKYO FM(80.0 MHz)を復調すると、次のようなバイト列が得られる。

$ rtl_fm -f 80.0M -M wbfm -s 200000 -r 48000 - | od -tx1z | head
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Tuner gain set to automatic.
Tuned to 80316000 Hz.
Oversampling input by: 6x.
Oversampling output by: 1x.
Buffer size: 6.83ms
Sampling at 1200000 S/s.
Output at 200000 Hz.
0000000 72 03 07 0c 5d 0a f2 05 ff fe c2 00 47 09 21 05  >r...].......G.!.<
0000020 17 ff 61 03 fb 03 9a 00 5a f5 18 fd fd fe c2 04  >..a.....Z.......<
0000040 12 ff 58 f7 cc f4 36 fd 80 ff be f9 63 fc 9e fb  >..X...6.....c...<
0000060 45 f5 d4 f8 0d fe f2 fc bd f8 21 f7 ae f0 84 f9  >E.........!.....<
0000100 4b f7 82 f5 21 f8 65 ff af 02 37 fe 77 f7 b5 f0  >K...!.e...7.w...<
0000120 e4 f2 04 ee 15 ec f8 f3 74 f1 c2 f7 4a f5 25 ef  >........t...J.%.<
0000140 af ed 94 f5 f6 f2 ed ef 80 f0 12 eb ce e4 31 ea  >..............1.<
0000160 b3 ea fd eb fc ec ed f3 e5 f2 91 f1 2f f1 b9 ef  >............/...<
0000200 33 f1 21 ec 89 e9 97 ec aa f3 b0 f4 d0 f2 2f f5  >3.!.........../.<
0000220 c2 f3 92 fa ff f6 a3 f9 3a fd cd ff ce 00 c9 ff  >........:.......<
Signal caught, exiting!

User cancel, exiting...

rtl_fmコマンドのオプションの意味は次の通り。

  • -f 80.0M: 受信周波数を80.0 MHzに合わせる
  • -M wbfm: 復調モードとしてWideband FMを指定
  • -s 200000: サンプリングレートを200 KHzに指定
  • -r 48000: リサンプリングレートを48 KHzに指定

得られたバイト列を次のようにaplayコマンドに渡すと、ALSAバイスからFMラジオの音声が流れる。

$ rtl_fm -f 80.0M -M wbfm -s 200000 -r 48000 - | aplay -r 48k -f S16_LE

aplayコマンドのオプションの意味は次の通り。

  • -r 48k: サンプリングレートを48 KHzとして再生
  • -f S16_LE: 入力バイト列をリトルエンディアンの16ビット符号付き整数として扱う

WAV形式で録音する場合は、avconvをインストールして次のようにすればよい。

$ sudo apt-get install libav-tools

$ rtl_fm -f 80.0M -M wbfm -s 200000 -r 48000 - | avconv -ar 48k -f s16le -t 10 -i - test.wav

$ aplay test.wav

上ではtest.wavに10秒間録音した後、再生している。

SDR#で周波数スペクトルを表示してみる

SDR#Windows用のSDRツールであり、GUIでスペクトルアナライザの表示や音声の復調・ノイズ除去を行うことができる。 ここでは、Raspberry Piで受信した電波をTCPを介してWindows端末のSDR#に転送してみる。

まず、rtl_tcpコマンドを使いTCPの1234ポートでサーバを起動する。

$ rtl_tcp -a 0.0.0.0
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Tuned to 100000000 Hz.
listening...
Use the device argument 'rtl_tcp=0.0.0.0:1234' in OsmoSDR (gr-osmosdr) source
to receive samples in GRC and control rtl_tcp parameters (frequency, gain, ...).

Windows端末にて、ダウンロードページから「SDR Software Package」をダウンロード・展開し、SDRSharp.exeを起動する。 続けて、次のように設定を行う。

  • Sourceペインで「RTL-SDR (TCP)」を選択
  • 設定ボタンを押し、Raspberry PiIPアドレスを指定
  • 再生ボタンを押す
  • 再度設定ボタンを押し、RF Gainを中央まで上げる
  • RadioペインからWFMを選択し、受信したい周波数に合わせる

設定ダイアログは、設定後次のスクリーンショットのようになる。

f:id:inaz2:20160728191654p:plain

80.0 MHzを受信した際のスクリーンショットを次に示す。

f:id:inaz2:20160728191514p:plain

スペクトルアナライザにて80.0 MHz周辺に山があること、同時にWindows端末上でFMラジオの音声が流れることが確認できる。

関連リンク

Raspberry PiにZabbixをインストールする

「Raspberry Pi 3でファイルサーバ兼iTunesサーバを作る」ではサーバ監視ツールとしてnetdataをインストールしたが、ディスク使用率の監視に難があるためZabbixに切り替えることにした。 ここでは、Raspberry PiにZabbixをインストールし、サーバの状態を表すグラフを一覧表示するダッシュボード(Screen)を作ってみる。

環境

Raspberry Pi 3 (Raspbian Jessie Lite)

$ uname -a
Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l GNU/Linux

$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

Zabbixのインストール

Raspbianのリポジトリには、バージョン2.2のパッケージが用意されている。 まず、マニュアルのインストール手順を参考に、必要なパッケージをインストールする。

$ sudo apt-get install zabbix-server-mysql zabbix-frontend-php
$ sudo apt-get install zabbix-agent
$ sudo apt-get install php5-mysql

次に、MySQL上にデータベースを作成する。パスワード(<PASSWORD>)は適宜置き換えること。

$ mysql -uroot -p
mysql> create database zabbix character set utf8 collate utf8_bin;
mysql> grant all privileges on zabbix.* to zabbix@localhost identified by '<PASSWORD>';
mysql> exit

$ cd /usr/share/zabbix-server-mysql
$ zcat schema.sql.gz | mysql -v -uzabbix -p zabbix
$ zcat images.sql.gz | mysql -v -uzabbix -p zabbix
$ zcat data.sql.gz | mysql -v -uzabbix -p zabbix

続けて、zabbix-serverおよびPHPの設定を行う。

$ sudo vi /etc/zabbix/zabbix_server.conf
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=<PASSWORD>

$ sudo service zabbix-server restart
$ sudo vi /etc/php5/apache2/php.ini
; Zabbix
post_max_size = 16M
max_execution_time = 300
max_input_time = 300
date.timezone = Asia/Tokyo

フロントエンドのファイル一式を公開ディレクトリに配置し、Apacheを再起動する。

$ sudo ln -s /usr/share/doc/zabbix-frontend-php/examples/apache.conf /etc/apache2/conf-available/zabbix.conf
$ sudo a2enconf zabbix
$ sudo service apache2 restart

ブラウザからhttp://<ipaddress>/zabbixにアクセスするとセットアップページが表示されるので、表示される手順に従い、最終的に生成される設定ファイルを所定のパスに書き込む。

$ sudo vi /etc/zabbix/zabbix.conf.php
<?php
// Zabbix GUI configuration file
global $DB;

$DB['TYPE']     = 'MYSQL';
$DB['SERVER']   = 'localhost';
$DB['PORT']     = '0';
$DB['DATABASE'] = 'zabbix';
$DB['USER']     = 'zabbix';
$DB['PASSWORD'] = '<PASSWORD>';

// SCHEMA is relevant only for IBM_DB2 database
$DB['SCHEMA'] = '';

$ZBX_SERVER      = 'localhost';
$ZBX_SERVER_PORT = '10051';
$ZBX_SERVER_NAME = '';

$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
?>

ログイン画面が表示されたら、デフォルトアカウントのAdmin/zabbixでログインする。 続けて、画面右上にあるProfileを開き、パスワードを変更しておく。

Screenを作る

Zabbixにおける各種オブジェクトは、おおむね次のような関係にある。

Host groups - Hosts - Items/Triggers/Graphs/Discovery/Web

Templates - Applications - Items
          - Triggers/Graphs/Discovery/Web

Screens - Graphs - Items

ここで、Hostsは個々のサーバ、Itemsは数値データとして表される監視項目、Triggersはアラートを上げる条件式に相当する。 また、GraphsはItemsを組み合わせて作られるグラフ、DiscoveryはマウントポイントやNICの列挙を行いItems等に展開するルーチン、ScreensはGraphsを組み合わせて作られるダッシュボードに相当する。 WebはHTTP(S)の監視に相当し、Zabbixサーバからアクセスした際のステータスコードやダウンロード速度、レスポンスタイムを監視することができる。

今回は、Configurations→Hostsから、標準で用意されているHost「Zabbix server」を有効化した。 さらに、Configurations→Screensから、「Raspberry pi」という名前のScreenを新規作成し、以下のGraphsを適当な位置、サイズで配置した。

  • Zabbix server: CPU load
  • Zabbix server: Memory usage
  • Zabbix server: Network traffic on eth0
  • Zabbix server: Disk space usage /

Monitoring→ScreensからScreen「Raspberry pi」を表示したときのスクリーンショットを次に示す。

f:id:inaz2:20160727162240p:plain

Raspberry PiのCPU温度をグラフ化する

Raspberry Pi(Raspbian)では、次のようにしてCPU温度を得ることができる。

$ cat /sys/class/thermal/thermal_zone0/temp
64451

上の場合、CPU温度は64.451度となる。 これを利用して、ZabbixでCPU温度もグラフ化してみる。

まず、ZabbixのConfigurations→Hostsから、「Zabbix server」のItemsを選択する。 「Create Item」ボタンから新規Itemを作成し、次のように入力する(参考)。

  • Name: Temperature
  • Type: Zabbix agent
  • Key: vfs.file.contents[/sys/class/thermal/thermal_zone0/temp]
  • Type of information: Numeric (float)
  • Units: ℃
  • Use custom multiplier: 0.001
  • Update interval (in sec): 60
  • History storage period (in days): 7
  • Trend storage period (in days): 365

ここでは、Custom multiplierを使うことで得られた値を度数に変換している。

続けて、「Zabbix server」のGraphsを選択する。 「Create Graph」ボタンから新規Graphを作成し、次のように入力する。

  • Name: Temperature
  • Itemsに「Zabbix server: Temperature」を追加

あとは、上で作成したScreenにこのGraphを配置すればよい。 作成されたグラフは次のスクリーンショットのようになる。

f:id:inaz2:20160727162248p:plain

備考

Monitoring→Dashboardの「Favorite screens」に作成したScreenを追加しておくと、アクセスが容易になる。 また、Monitoring→Latest dataを見ることで、各Itemの最新の値を確認することができる。

/etc/zabbix/externalscriptsの下に実行権限を付与したシェルスクリプトを置くことで、External checksとして標準出力をItemにすることができる。 ただし、パフォーマンスが落ちるため多用すべきではない。

Google Sheetsでスクレイピング結果を定期的に記録する

Google Docs表計算アプリであるGoogle Sheetsでは、Google Apps Scriptと呼ばれるJavaScriptベースのスクリプト言語でマクロを書くことができる。 また、Google Apps ScriptではTriggerと呼ばれる機能により特定の関数を定期的に実行することができる。

Google Apps Scriptで特定のページをスクレイピングし、その結果をスプレッドシートに新しい行として追記するスクリプトを書くと次のようになる。 ここではスクレイピング対象として、Amazonから商品の新品価格を取得している。

function main() {
  var date = Utilities.formatDate(new Date(), 'JST', 'yyyy/MM/dd');
  var value1 = getDataFromUrl('https://www.amazon.co.jp/dp/B00UJK322O', /新品の出品:\d+<\/a><span class='a-color-price'>¥ ([\d,]+)<\/span>より<\/span>/);
  addNewRow([date, value1]);
}

function addNewRow(values) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];
  var firstEmptyRow = sheet.getLastRow() + 1;
  for (i=0; i<values.length; i++) {
    sheet.getRange(firstEmptyRow, i+1).setValue(values[i]);
  }
}

function getDataFromUrl(url, re) {
  var data = UrlFetchApp.fetch(url);
  var text = data.getContentText();
  Logger.log(text);
  return text.match(re)[1];
}

ここで、getDataFromUrl関数はURLと正規表現オブジェクトを引数に取り、正規表現の一つ目のキャプチャの内容を返す関数になっている。

あとは、Trigger機能でmain関数を定期的に実行するように設定すればよい。

メッセージダイジェスト(MD)、メッセージ認証コード(MAC)、鍵導出関数(KDF)の違いについてのメモ

「ハッシュ」という言葉があいまいに使われている場面をしばしば目にするので、関係する概念とそれらの違いについてまとめてみる。

メッセージダイジェスト(Message Digest; MD)

MD5SHA-1、SHA-256など、あるバイト列(メッセージ)に対し固定長の要約値を求めるアルゴリズム。 メッセージの同一性判定に用いられる。

同一の要約値となる(異なる)メッセージの組を求めることが計算量的に困難(強衝突耐性)なものをメッセージダイジェストと呼び、暗号学的ハッシュ関数とも呼ばれる。 同一の要約値となるメッセージの組が容易に求められるものは、誤り検出符号と呼ばれ区別される。 CRC32は誤り検出符号の一種である。

PythonでSHA-256を用いてメッセージダイジェストを求める例を次に示す。

$ python
Python 2.7.5 (default, Oct  2 2013, 22:34:09)
[GCC 4.8.1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hashlib
>>> hashlib.sha256('foobar').hexdigest()
'c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2'

メッセージ認証コード(Message Authentication Code; MAC

あるバイト列(メッセージ)に対し共通鍵を用いて固定長のバイト列を求めるアルゴリズム。 メッセージの改ざん検知に用いられる。

共通鍵を用いる点においてメッセージダイジェストと異なり、完全性を保護しメッセージの改ざんを防ぐことができる。 つまり、メッセージダイジェストではメッセージ改ざん後の値を容易に計算できるのに対し、メッセージ認証コードでは共通鍵がなければ計算できない。 また、デジタル署名とは公開鍵ではなく共通鍵を用いている点において異なり、否認防止の性質をもたない。 つまり、デジタル署名では公開鍵の持ち主がメッセージを生成したことが保証されるのに対し、メッセージ認証コードでは誰がメッセージを生成したかを特定することはできない。

メッセージ認証コードには、ハッシュ関数を用いる方式(HMAC)とブロック暗号アルゴリズムを用いる方式(CBC-MACなど)がある。 PythonでSHA-256を用いたHMACを求める例を次に示す。

$ python
Python 2.7.10 (default, Jun  1 2015, 18:05:38)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import hashlib
>>> import hmac
>>> key = os.urandom(16)
>>> hmac.new(key, 'foobar', hashlib.sha256).hexdigest()
'05d531abfb693adcb3adbdc0cd3800404636fd1726ad851c86e61683cf33c7f0'

鍵導出関数(Key Derivation Function; KDF)

秘密のバイト列(マスター鍵)から固定長の新たな鍵となるバイト列を求める(導出する)アルゴリズム。 ブロック暗号アルゴリズムに用いるのに適した、固定長で一定のエントロピーを持つより安全な鍵を得ることができる。 また、パラメータに繰り返し回数などを取ることで計算量を調整できるようになっており、導出された鍵からマスター鍵を総当たりで求めることが難しくなっている。 このため、データベースに保存しておくためのパスワードの安全な変換に適している。

Python(2.7.8、3.4以降)でHMAC SHA-256を用いたPBKDF2により新たな鍵を求める例を次に示す。

$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import hashlib
>>> import binascii
>>> salt = os.urandom(16)
>>> derived_key = hashlib.pbkdf2_hmac('sha256', b'foobar', salt, 100000)
>>> binascii.hexlify(derived_key)
b'e3fddc16c83da4ef7f6942f90111b2f129ec8b528a8ae8373ad89592285fab6c'