音声ファイルの切貼り
2021.10.10
YouTube でも紹介しています。画像をクリックすると再生できます。
今回は音声ファイルを切り貼りして、喋らせてみました。また、音声ファイルへの別ファイル埋め込みも行っています。
音源には、音声合成ソフト「UTAU」用に様々な音声ファイルが公開されています。
この記事では音声ファイル集『小春音アミ』を利用しています。
■「UTAU」用音声ファイル
あみたろの声素材工房 小春音アミ
サイト左側のメニュー・音源ダウンロードから「単独音3.00」を選んでダウンロードします。
ダウンロードした koharuneami_0300.zip を解凍すると、小春音アミ・ディレクトリの下に四音階の声素材ディレクトリが展開されます。
<小春音アミ>
┣<B4>
┣<C4>
┣<E4>
┣<G4>
・・・・
|
4音階(C4低音、E4、G4、B4裏声)
|
例えば、E4ディレクトリの中には様々な声素WAVファイルがはいっています。
あ_E4.wav
い_E4.wav
う_E4.wav
・・・・
き_E4.wav
ぎ_E4.wav
きぇ_E4.wav
きゃ_E4.wav
・・・・
UTAU 音声ファイルスペック |
ファイル名 | あ.wav、い.wav、う.wav など |
ファイル形式 | wav形式、PCM / 44100 / 16bit |
■声音源の確認
念のため、WAVファイルの形式を確認してみましょう。
Ref.音ファイル(拡張子:WAVファイル)のデータ構造について
WAVファイルの先頭44バイトのヘッダー情報を表示するプログラムです。
$ vi check_wavfile.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
unsigned short BlockAlign;
unsigned short BitPerSample;
char Subchunk2ID[4];
unsigned int Subchunk2Size;
} WAVE_FORMAT;
int main(int argc, char** argv) {
FILE *infp;
WAVE_FORMAT audio;
char str[32];
if (!(infp=fopen(argv[1],"rb"))) return 0;
fread(&audio,sizeof(WAVE_FORMAT),1,infp);
memset(str,0,sizeof(str));
memcpy(str,audio.ChunkID,sizeof(audio.ChunkID));
printf("ChunkID = %s\n",str);
printf("chunkSize = %d\n",audio.ChunkSize);
memcpy(str,audio.Format,sizeof(audio.Format));
printf("Format = %s\n",str);
memcpy(str,audio.Subchunk1ID,sizeof(audio.Subchunk1ID));
printf("Subchunk1ID = %s\n",str);
printf("Subchunk1Size = %d\n",audio.Subchunk1Size);
printf("AudioFormat = %d\n",audio.AudioFormat);
printf("NumChannels = %d\n",audio.NumChannels); // 1: mono or 2: stereo
printf("SampleRate = %d\n",audio.SampleRate); // 8kHz:8000 , 16kHz:16000, ...
printf("ByteRate = %d\n",audio.ByteRate);
printf("BlockAlign = %d\n",audio.BlockAlign);
printf("BitPerSample = %d\n",audio.BitPerSample); // 8bit or 16bit
memcpy(str,audio.Subchunk2ID,sizeof(audio.Subchunk2ID));
printf("Subchunk2ID = %s\n",str);
printf("Subchunk2Size = %d\n",audio.Subchunk2Size);
fclose(infp);
return 1;
}
$ gcc -Wall -o check_wavfile check_wavfile.c
$ ./check_wavfile あ_E4.wav
ChunkID = RIFF ← RIFF で固定
chunkSize = 64406 ←ファイルサイズ - (ChunkID[4]+chunkSize[4])
Format = WAVE
Subchunk1ID = fmt ← fmt で固定
Subchunk1Size = 16 ← リニアPCMの場合16
AudioFormat = 1 ← 非圧縮リニアPCMフォーマットは1
NumChannels = 1 ← モノラル:1/ステレオ:2
SampleRate = 44100
ByteRate = 88200 ← サンプリング周波数 x ブロックサイズ
BlockAlign = 2 ← モノラル16bit:2/ステレオ16bit:4
BitPerSample = 16 ← 1サンプルに必要なビット数
Subchunk2ID = data ← data で固定
Subchunk2Size = 64370 ← ファイルサイズ - 44
「あ」(あ_E4.wav)の声を聴いてみましょう。
$ aplay あ_E4.wav
0..73秒(Subchunk2Size/(SampleRate*BlockAlign))の長さがあります。
■WAVファイルの内容確認
次に、WAVファイル(あ_E4.wav)の中身をみてみます。
バイナリーのWAVファイルを配列に変換して出力しています。
$ vi bin2array.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
unsigned short BlockAlign;
unsigned short BitPerSample;
char Subchunk2ID[4];
unsigned int Subchunk2Size;
} WAVE_FORMAT;
int main(int argc, char** argv) {
FILE *infp, *outfp;
WAVE_FORMAT audio;
unsigned int filesize, column;
char fname[16];
unsigned char byte;
if (!(infp=fopen(argv[1],"rb"))) return 0;
fread(&audio,sizeof(WAVE_FORMAT),1,infp);
filesize = audio.ChunkSize + 8;
rewind(infp);
sprintf(fname,"%s.h",argv[2]);
outfp=fopen(fname,"w+");
fprintf(outfp, "unsigned char %s[%d] = {\n",argv[2],filesize);
for (column=0;filesize>0;column++) {
fread(&byte,sizeof(unsigned char),1,infp);
if ((--filesize)==0) {
fprintf(outfp,"0x%02x};\n",byte);
} else if ((column+1)%16) {
fprintf(outfp,"0x%02x,",byte);
} else {
fprintf(outfp,"0x%02x,\n",byte);
}
}
fclose(infp);
fclose(outfp);
return 1;
}
$ gcc -Wall -o bin2array bin2array.c
$ ./bin2array あ_E4.wav A
A.h が生成されます。
unsigned char A[64414] = {
0x52,0x49,0x46,0x46,0x96,0xfb,0x00,0x00,0x57,0x41,
0x56,0x45,0x66,0x6d,0x74,0x20,0x10,0x00,0x00,0x00,
0x01,0x00,0x01,0x00,0x44,0xac,0x00,0x00,0x88,0x58,
0x01,0x00,0x02,0x00,0x10,0x00,0x64,0x61,0x74,0x61,
0x72,0xfb,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
~
0x00,0x00,0x00,0x00,0xf0,0xff,0xe5,0xff,0xe5,0xff,
0xde,0xff,0xd9,0xff,0xd4,0xff,0xcc,0xff,0xcd,0xff,
0xcc,0xff,0xda,0xff,0xee,0xff,0xf4,0xff,0x00,0x00,
~
0x7b,0x03,0xec,0x02,0x8c,0x02,0x03,0x02,0x33,0x01,
0x6c,0x00,0xf8,0xff};
44バイトのWAVヘッダーのあとに無音部分があり、
続いて、声のデータがあります。
■音声ファイルの部分抽出
この無音部分のあとの0.25秒分を切り出してみます。
ヘッダー情報のチャンクサイズとサブチャンク2サイズを変更して、ファイルに書き出します。
それに続けて、無音部分を飛ばして、抽出した(SampleRate/2)バイト分の音声データを出力します。
1サンプルに必要なビット数は16ビットなので、0.25秒分になります。
datasize = audio.SampleRate / 2;
audio.ChunkSize = datasize + sizeof(WAVE_FORMAT) - 8;
audio.Subchunk2Size = datasize;
fwrite(&audio,sizeof(WAVE_FORMAT),1,outfp);
$ vi extract.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
unsigned short BlockAlign;
unsigned short BitPerSample;
char Subchunk2ID[4];
unsigned int Subchunk2Size;
} WAVE_FORMAT;
int main(int argc, char** argv) {
FILE *infp, *outfp;
WAVE_FORMAT audio;
unsigned int datasize;
char fname[16];
unsigned char byte;
if (!(infp=fopen(argv[1],"rb"))) return 0;
fread(&audio,sizeof(WAVE_FORMAT),1,infp);
datasize = audio.Subchunk2Size;
sprintf(fname,"%s.wav",argv[2]);
outfp=fopen(fname,"w+b");
// 無音部分の読み飛ばし
while (1) {
fread(&byte,1,1,infp);
if ((byte==0x00)||(byte==0x01)) {
fread(&byte,1,1,infp);
} else {
fread(&byte,1,1,infp);
break;
}
}
datasize = audio.SampleRate / 2;
audio.ChunkSize = datasize + sizeof(WAVE_FORMAT) - 8;
audio.Subchunk2Size = datasize;
fwrite(&audio,sizeof(WAVE_FORMAT),1,outfp);
for (int cnt=0; cnt < datasize; cnt++) {
fread(&byte,1,1,infp);
fwrite(&byte,1,1,outfp);
}
fclose(infp);
fclose(outfp);
return 1;
}
$ gcc -Wall -o extract extract.c
$ ./extract あ_E4.wav A
$ aplay A.wav
■モノラル8ビット変換
モノラル16ビットから8ビットに落としてみました。
datasize = audio.SampleRate / 2;
audio.ChunkSize = datasize + sizeof(WAVE_FORMAT) - 8;
audio.ByteRate = audio.SampleRate;
audio.BlockAlign = 1;
audio.BitPerSample = 8;
audio.Subchunk2Size = datasize / 2;
fwrite(&audio,sizeof(WAVE_FORMAT),1,outfp);
for (int cnt=0; cnt < datasize; cnt+=2) {
fread(&byte2,2,1,infp);
byte = (byte2>>8)&0x00ff;
fwrite(&byte,1,1,outfp);
}
$ vi conv16to8.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
unsigned short BlockAlign;
unsigned short BitPerSample;
char Subchunk2ID[4];
unsigned int Subchunk2Size;
} WAVE_FORMAT;
int main(int argc, char** argv) {
FILE *infp, *outfp;
WAVE_FORMAT audio;
unsigned int datasize;
char fname[16];
unsigned char byte;
unsigned short byte2;
if (!(infp=fopen(argv[1],"rb"))) return 0;
fread(&audio,sizeof(WAVE_FORMAT),1,infp);
datasize = audio.Subchunk2Size;
sprintf(fname,"%s.wav",argv[2]);
outfp=fopen(fname,"w+b");
// 無音部分の読み飛ばし
while (1) {
fread(&byte,1,1,infp);
if ((byte==0x00)||(byte==0x01)) {
fread(&byte,1,1,infp);
} else {
fread(&byte,1,1,infp);
break;
}
}
datasize = audio.SampleRate / 2;
audio.ChunkSize = datasize + sizeof(WAVE_FORMAT) - 8;
audio.ByteRate = audio.SampleRate;
audio.BlockAlign = 1;
audio.BitPerSample = 8;
audio.Subchunk2Size = datasize / 2;
fwrite(&audio,sizeof(WAVE_FORMAT),1,outfp);
for (int cnt=0; cnt < datasize; cnt+=2) {
fread(&byte2,2,1,infp);
byte = (byte2>>8)&0x00ff;
fwrite(&byte,1,1,outfp);
}
fclose(infp);
fclose(outfp);
return 1;
}
$ gcc -Wall -o conv16to8 conv16to8.c
$ ./conv16to8 あ_E4.wav A8
$ aplay A8.wav
■声をつなぎ合わせます
声ファイルを切り貼りして、しゃべらせてみます。
$ vi speech.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
unsigned short BlockAlign;
unsigned short BitPerSample;
char Subchunk2ID[4];
unsigned int Subchunk2Size;
} WAVE_FORMAT;
unsigned int pos = 0;
unsigned char *data;
WAVE_FORMAT audio;
int extractVoice(char *fname) {
FILE *infp;
unsigned char byte;
int blocksize;
if (!(infp=fopen(fname,"rb"))) return 0;
fread(&audio,sizeof(WAVE_FORMAT),1,infp);
if (pos==0) {
blocksize = audio.SampleRate / 2;
data = (unsigned char *)malloc(blocksize*100);
} else {
blocksize = audio.SampleRate / 2;
}
// 無音部分の読み飛ばし
while (1) {
fread(&byte,1,1,infp);
if ((byte==0x00)||(byte==0x01)) {
fread(&byte,1,1,infp);
} else {
fread(&byte,1,1,infp);
break;
}
}
fread(&data[pos],blocksize,1,infp);
pos+=blocksize;
fclose(infp);
return 1;
}
int main(int argc, char** argv) {
FILE *outfp;
extractVoice("ど_E4.wav");
extractVoice("う_E4.wav");
extractVoice("も_E4.wav");
extractVoice("れ_E4.wav");
extractVoice("い_E4.wav");
extractVoice("む_E4.wav");
extractVoice("で_E4.wav");
extractVoice("す_E4.wav");
audio.ChunkSize = sizeof(WAVE_FORMAT) - 8 + pos;
audio.Subchunk2Size = pos;
outfp=fopen("speech.wav","w+b");
fwrite(&audio,sizeof(WAVE_FORMAT),1,outfp);
fwrite(data,pos,1,outfp);
free(data);
fclose(outfp);
return 1;
}
$ gcc -Wall -o speech speech.c
$ ./speech
$ aplay speech.wav
長音が含まれる場合は、その音に続けて、母音を、促音(そくおん)の場合は、さらに音を短くして、そのあとに、
無音部分を挿入すると、うまくいくかもしれません。
■応用例
音声ファイルに別のファイルを埋め込んでみます。
音声データの最下位1ビットを埋め込みファイル用に使用します。
$ vi implant.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
typedef struct {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
char Subchunk1ID[4];
unsigned int Subchunk1Size;
unsigned short AudioFormat;
unsigned short NumChannels;
unsigned int SampleRate;
unsigned int ByteRate;
unsigned short BlockAlign;
unsigned short BitPerSample;
char Subchunk2ID[4];
unsigned int Subchunk2Size;
} WAVE_FORMAT;
int main(int argc, char** argv) {
FILE *infp, *textfp, *impfp;
WAVE_FORMAT audio;
unsigned int datasize;
long statsize;
unsigned short textsize, implantsize;
unsigned char byte, txbyte;
struct stat statBuf;
unsigned char id = 'X';
if (!(infp=fopen(argv[1],"rb"))) return 0;
fread(&audio,sizeof(WAVE_FORMAT),1,infp);
datasize = audio.Subchunk2Size;
// テキストファイルの埋め込み
if (argc==4) {
if (stat(argv[2], &statBuf) == 0)
statsize = statBuf.st_size;
textsize = (unsigned short)statsize;
implantsize = (textsize + 3) * 8; // 3: length + 識別子
if (datasize < implantsize) {
printf("WAV File is too short!\n");
return 0;
}
impfp=fopen(argv[3],"w+b");
fwrite(&audio,sizeof(WAVE_FORMAT),1,impfp);
// 識別子付加
for (int i=0; i < 8; i++, datasize--) {
fread(&byte,1,1,infp);
byte = (byte&0xfe) | ((id>>i)&0x01);
fwrite(&byte,1,1,impfp);
}
// 埋め込みファイルサイズ付加
for (int i=0; i < 16; i++, datasize--) {
fread(&byte,1,1,infp);
byte = (byte&0xfe) | (unsigned char)((textsize>>i)&0x0001);
fwrite(&byte,1,1,impfp);
}
// テキストファイル埋め込み
textfp=fopen(argv[2],"rb");
while (textsize>0) {
fread(&txbyte,1,1,textfp);
for (int i=0; i < 8; i++, datasize--) {
fread(&byte,1,1,infp);
byte = (byte&0xfe) | ((txbyte>>i)&0x01);
fwrite(&byte,1,1,impfp);
}
textsize--;
}
// 残りのWAVファイル出力
while (datasize>0) {
fread(&byte,1,1,infp);
fwrite(&byte,1,1,impfp);
datasize--;
}
fclose(textfp);
fclose(impfp);
// テキストファイルの取り出し
} else if (argc==2) {
// 識別子取得
txbyte = 0x00;
for (int i=0; i < 8; i++, datasize--) {
fread(&byte,1,1,infp);
txbyte |= (byte & 0x01)<<i;
}
if (txbyte!=id) {
printf("File not included!\n");
return 0;
}
// 埋め込みファイルサイズ取得
textsize = 0;
for (int i=0; i < 16; i++, datasize--) {
fread(&byte,1,1,infp);
textsize |= (byte & 0x01)<<i;
}
// テキストファイル取り出し
while (textsize>0) {
txbyte = 0x00;
for (int i=0; i < 8; i++) {
fread(&byte,1,1,infp);
txbyte |= (byte & 0x01)<<i;
}
putc(txbyte,stdout);
textsize--;
}
}
fclose(infp);
return 1;
}
$ gcc -Wall -o implant implant.c
音声ファイルあ_E4.wavに、プログラムimplant.cを埋め込んでみます。
埋め込み前後で音声ファイルのサイズは変わりません。
$ ./implant あ_E4.wav implant.c Aimp.wav
$ aplay Aimp.wav
音声ファイルから、埋め込んだプログラムを取り出してみます。
$ ./implant Aimp.wav
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
typedef struct {
char ChunkID[4];
unsigned int ChunkSize;
char Format[4];
~
あらかじめ相手に埋め込み・抽出プログラムを渡しておくと、ボイスメッセージとともに資料を閲覧するという使い方もできます。`
ここで、音声ファイルのノイズが気になる場合は、2バイト分の最下位1ビットをデータに使用するように改造するとよいと思います。
また、より複雑な埋め込みアルゴリズムを使うことで機密性が向上します。
■その他文献
・Julius 汎用大語彙連続音声認識エンジン
|
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
Arduinoで学ぶ組込みシステム入門(第2版)
●Arduinoを使って組込みシステム開発を理解する
・ハードウェアやソフトウェアなどの基礎知識/
・設計から実装までを系統的に説明するモデルベース開発/
・Arduinoを用いた実際の開発例
最新 使える! MATLAB 第3版
◆◆すぐに「使える!」 全ページフルカラー!◆◆
・MATLAB R2022bに対応し、解説もより詳しく!/
・コマンド・スクリプトの例が豊富で、動かして学べる!/
・超基本から解説。これから使いはじめる人にぴったり!/
・全編フルカラー、スクリーンショットも豊富!
Amazon Web Services基礎からのネットワーク&サーバー構築改訂4版
1.システム構築をインフラから始めるには/
2.ネットワークを構築する/
3.サーバーを構築する/
4.Webサーバーソフトをインストールする/
5.HTTPの動きを確認する/
6.プライベートサブネットを構築する/
7.NATを構築する/
8.DBを用いたブログシステムの構築/
9.TCP/IPによる通信の仕組みを理解する
C言語は第二の母国語: 独学学生時代から企業内IT職人時代に培った、独立のための技術とノウハウ 平田豊著
学生時代から独学でプログラミングをはじめ、企業内でデバイスドライバを開発し、そして独立後もたくさんのアプリケーション開発や技術書制作に携わってきた著者。その筆者が大事に使い続ける「C言語」の“昔と今”について、気づいたことや役立つ知識、使ってきたツールなどについて、これまで記してきたことを整理してまとめました。
本書では、現役プログラマーだけでなく、これからプログラミングを学ぶ学生などにも有益な情報やノウハウを、筆者の経験を元に紹介しています。
1冊ですべて身につくJavaScript入門講座
・最初の一歩が踏み出せる! 初心者に寄り添うやさしい解説
・最新の技術が身につく! 今のJavaScriptの書き方・使い方
・絶対に知っておきたい! アニメーションとイベントの知識
・プログラミングの基本から実装方法まですべて学べる
図解! Git & GitHubのツボとコツがゼッタイにわかる本
ソフトウェア開発では欠かすことのできないGit、GitHub。
これからGit、GitHubを使いたいという入門者の方でも、実際に手を動かしながら使い方を学べます。
C自作の鉄則!2023 (日経BPパソコンベストムック)
メーカー製のパソコンはスペックが中途半端で、自分が本当に欲しい機種がない――。そう思っている人には、ぜひ自作パソコンをお薦めします。自作パソコンのパーツは進化が速く、しかも驚くほど種類が豊富。価格も性能も、幅広く用意されているため、満足度100%の“自分だけの1台”を手に入れることができます。
Interface 2023年6月号
特集:第1部 フィルタ設計 基礎の基礎/
第2部 係数アプリや波形観測アプリで合点!FIR&IIRフィルタ作り/
第3部 配布プリント基板で体験!マイコンで動くフィルタ作り
日経Linux 2023年5月号
【特集 1】 AI時代の最強フリーソフト ~ 25のやりたいを実現!
【特集 2】 AWS、Azureのうまみを無料で体感!面倒なことはクラウドに任せよう
【特集 3】 新しいRaspberry Pi Cameraで遊んでみよう
【特集 4】 Linuxで旧型PCを復活! 1kg切るモバイルPCを「ChromeOS Flex」でChromebook化
ラズパイマガジン2022年秋号
特集:5大人気ボード 電子工作超入門
「半導体不足で在庫が不足し、電子工作のボードがなかなか買えない…」。そんな今にふさわしい特集を企画しました。5種の人気ボードにすべて対応した電子工作の入門特集です。「GPIO」や「I2C」を使った電子パーツの制御方法は、どのボードでも同じです。手に入れられたボードを使って、今こそ電子工作を始めましょう。
地方で稼ぐ! ITエンジニアのすすめ
学歴、理系の知識、専門スキル……全部なくてもITエンジニアになれる!
地方でも高収入でやりがいをもって働ける!ITエンジニアの魅力を一挙大公開
Raspberry Piのはじめ方2022
本書は、ラズパイやPicoの買い方やインストール、初期設定といった基本から、サーバー、電子工作、IoT、AIといったラズパイならではの活用方法まで、1冊でお届けします。
ラズパイをこれから始める方向けに、全36ページの入門マンガ「女子高生とラズベリーパイ」も巻末に掲載。これを読むだけでラズパイがどんなものなのか、すぐに分かって触れるようになります。
ハッカーの学校 IoTハッキングの教科書
生活にとけこみ、家電機器を便利にするIoT技術。
Webカメラなど、便利の裏側に潜むセキュリティの危険性をハッキングで検証。
専門家がパケットキャプチャからハードウェアハッキングまで、その攻撃と防御を徹底解説。
本書は2018年7月に刊行された「ハッカーの学校IoTハッキングの教科書」に一部修正を加えた第2版です。
攻撃手法を学んで防御せよ! 押さえておくべきIoTハッキング
本書は、経済産業省から2021年4月にリリースされた、IoTセキュリティを対象とした『機器のサイバーセキュリティ確保のためのセキュリティ検証の手引き』の『別冊2 機器メーカに向けた脅威分析及びセキュリティ検証の解説書』をもとに、IoT機器の開発者や品質保証の担当者が、攻撃者の視点に立ってセキュリティ検証を実践するための手法を、事例とともに詳細に解説しました。
ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS…
全WEB媒体で効果バツグン!
カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術
プログラマーは世界をどう見ているのか 西村博之著
イーロン・マスク(テスラ)、ジェフ・べゾス(Amazon)、ラリー・ペイジ(Google)…etc.
世界のトップはなぜプログラマーなのか?
ニーア オートマタ PLAY ARTS改 <ヨルハ 二号 B型 DX版> PVC製 塗装済み可動フィギュア
「NieR:Automata」より、ヨルハ二号B型こと2BがPLAY ARTS改に新たに登場!
高級感の感じられるコスチュームや髪の質感、洗練されたボディバランス、細かなデティールに至るまでこだわり抜かれた逸品。
DX版には通常版のラインナップに加え2Bの随行支援ユニット ポッド042などをはじめ“純白の美しい太刀"白の約定やエフェクトパーツ、自爆モードを再現できる換装用ボディパーツ、シーンに合わせて変えられる顔パーツ2種も付属する豪華な仕様に。
作中のあらゆるシーンを再現することが可能なファン必見の一品となっている。
Newtonライト2.0 ベイズ統計
ベイズ統計は,結果から原因を推定する統計学です。AIや医療などの幅広い分野で応用されています。その基礎となるのは18世紀に考えだされた「ベイズの定理」です。
この本では,ベイズ統計学のきほんをやさしく紹介していきます。
白光(HAKKO) ダイヤル式温度制御はんだ吸取器 ハンディタイプ FR301-81
無水エタノールP 500mlx2個パック(掃除)
ケイバ(KEIBA) マイクロニッパー MN-A04
サンハヤト SAD-101 ニューブレッドボード
白光(HAKKO) HEXSOL 巻はんだ 精密プリント基板用 150g FS402-02
[Amazon限定ブランド]【指定第2類医薬品】PHARMA CHOICE 解熱鎮痛薬 解熱鎮痛錠IP 100錠
|