Rustのデータ型2

ブール値

fn main(){
	let t = true;
	let f: bool = false;

	println!("{} {}", t, f);
}

キャラクタ

fn main(){
	let c = 'z';
	let n:char = '0';
	let jp = 'あ';

	println!("{} {} {}", c, n, jp);
}

b’~’で囲んだASCII文字はバイト文字として扱われる
let chb = b’a’;
let ch = ‘a’;
let chjp = ‘あ’;

文字列
RustにはstrとStringの2種類がある。String型はプリミティブなデータ型ではない。strは文字列スライトという
let msg:&str = “Hello, Dogs!”;
let s = &msg[2..5];

fn main(){
	let msg:&str = "Hello, Dogs!";

	println!("msg.len()={}", msg.len());
	println!("msg={}", msg);
	println!("msg={}", &msg[2..5]);
}
fn main(){
	let dog = "ポチ";
	let msg = format!("{} ({}歳)", dog, 6);
	println!("{}", msg);
}
fn main(){
	let mut msg:String = String::from("Hello");
	msg = msg + " Rust!";

	println!("{}", msg);
}

push_str, insert_str, +がある

fn main(){
	let mut msg = String::from("ポチ");
	msg.push_str("Good Dog");

	println!("{}", msg);
}
fn main(){
	let mut s = String::from("ポチ");
	s.insert_str(0, "Hello");

	println!("{}", s);
}
fn main(){
	let mut msg = String::from("ポチ");
	msg = msg + "Good Dog";

	println!("{}", msg);
}

Rustのデータ型1

Rustのデータ型は整数(integer)、浮動小数点(floating-point number)、ブール値(Boolean)、キャラクタ(character)という4種類のスカラー型(scalar type)と、タプル(tuple)と配列(array)という2種類の複合型(Compound Type)などがある

### Rustのプリミティブ型
bool, char, f32(32ビット浮動小数点型), f64(64ビット浮動小数点型), fn(関数ポインタ), i8(8ビット符号付き整数), i16(16ビット符号付き整数), i32(32ビット符号付き整数),  i64(64ビット符号付き整数),  i128(128ビット符号付き整数), isize(ポインタのサイズの符号付き整数), str(文字列スライス型), tuple, u8(8ビット符号なし整数), u16(16ビット符号なし整数), u32(32ビット符号なし整数), u64(64ビット符号なし整数), u128(128ビット符号なし整数), usize(ポインタのサイズの符号なし整数), *const(ポインタ型(unsafe*)), *mut(ポインタ型(unsafe*)), &(参照型), スライス(スライス型), ()(unit型), !(never型), [](配列)

u8: 0~255
u16: 0~65535
u32: 0~4294967295
u64: 0~18446744073709551615
u128

i8: -128~127
i16: -32768~32767
i32: -2147483648 ~ -2147483647
i64: -9223372036854775808 ~ 9223372036854775807
i128
unsize, isize

整数
let x = 18;
桁の大きい10進数整数
const MAX_POINTS: u32 = 100_000;
16進数
let x = 0x12;
8進数
let x = 0o22;
2進数
let x = 0b010010;
桁の大きい2進数
let x = 0b01_0010;
let u b’A’; let a = b’;’; let a = b’あ’;
リテラルの型を明示
let n = 3_i16;

浮動小数点
f32: 32ビット浮動小数点数
f64: 64ビット浮動小数点数

fn main(){
	let x = 7.0;
	println!("{}", type_of(x));
}

fn type_of<T>(_: T) -> &'static str {
	std::any::type_name::<T>()
}

型を指定するときはf32, f64を使う

fn main(){
	let x: f32 = 7.0;
	let y: f64 = 0.3;

	println("x*y={}", x as f64 * y);
}
fn main(){
	let x: f32 = 7.0;
	let y = 3.2;

	println!("{} {} {}", x, y, x + y);
}

Rustの基本的な要素

名前: 半角英字

fn main(){
	let age = 10;
	println!("age={}", age);
}
fn main(){
	let dog1_age = 10;
	println!("dog1_age={}", dog1_age);
}

先頭に「_」を付けたり、「_」だけの名前は使わない変数を表す

fn main(){
	let mut _a = 9;
	let _ = 12;

	println!("表示する値がありません");
}

式は let x = 5; などと表す
関数の場合は printdata(a, b); など。何もしない時は()を使うことがよくある

Rustのプロジェクトとビルド

大規模なプログラムを作成する場合は関連ファイルをプロジェクトと呼ぶ単位で扱うと便利なことがある
プロジェクトを作成するには、作成したいフォルダでcargo newを実行する

$ cargo new helloprj —bin
Created binary (application) `helloprj` package
$ cd helloprj
$ tree
.
├── Cargo.toml
└── src
└── main.rs

main.rs

fn main() {
    println!("Hello, world!");
}

$ cargo build

buildして実行する場合
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target/debug/helloprj`
Hello, world!

Rust playground
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021

Rustを始める

従来のプログラミング言語の優れた点を採用し、問題点を排除して作成された

// dispfile.rs
use std::env;
use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;

fn main() -> std::io::Result<()> {
	let argv: Vec<String> = env::args().collect(); // コマンドライン引数
	if argv.len() < 2 {
		println!("引数にファイル名を指定してください。");
		std::process:exit(1);
	}

	let f = File::open(&argv[1])?;
	let reader = BufReader::new(f);

	for line in reader.lines() {
		println!("{}", line?);
	}
	Ok(())
}

OpenSSLと楕円曲線暗号

$ openssl ecparam -list_curves

ECDSAで署名の生成・検証をする
$ echo abcde > plain.txt
$ openssl ecparam -genkey -name secp112r1 -out key-pair.pem
$ openssl ec -in key-pair.pem -outform PEM -pubout -out public.pem
$ openssl ec -in key-pair.pem -outform PEM -out private.pem
$ openssl dgst -sha1 -sign private.pem plain.txt > signature.dat
$ openssl dgst -sha1 -verify public.pem -signature signature.dat plain.txt
$ openssl asn1parse -inform DER -in signature.dat
0:d=0 hl=2 l= 34 cons: SEQUENCE
2:d=1 hl=2 l= 15 prim: INTEGER :D8BBE81DBD2E3A576952570B88D6
19:d=1 hl=2 l= 15 prim: INTEGER :B655B2C4FB75815E84B67BC4356E

sha256とsha512

SHA–256は入力値ごとに固有のハッシュ値を生成することにより、データの完全性などをチェックするために用いられる

$original_string = "パスワード";
$hashed_string = hash('sha256', $original_string);
print_r($hashed_string);

$ php index.php
d8b076148c939d9d2d6eb60458969c486794a4c0fcf0632be58fa5bf6d15aafa

$original_string = "パスワード";
$hashed_string = hash('sha512', $original_string);
print_r($hashed_string);

e2f8de62a90c1e3039cba62afb7646401ca5fbd97ec4ef3fbada4752aeafd022cfa7eafda320d08b2df6a0a6e55f0d62b5967081792095d7eaafc58d00533283

512にすると倍になってますね。

署名

署名は署名者アリスと受け取ったデータの正当性を確認したいボブの二人の間で使用する

1. 鍵生成: 署名鍵sと検証鍵Sのペアを作成する
2. 署名: アリスは署名したいデータmに足して署名鍵sで検証に使うためのデータΩを作成する これを署名という
3. 検証: データと署名の組み合わせをもらったボブはアリスから受け取った検証鍵Sを用いて検証する

メッセージ認証符号MAC(Message Authentication Code)

MACはデータの完全性を保証するための仕組み

1.初期化:事前に秘密鍵sを決めて共有しておく 
2.MAC生成: データmと秘密鍵sからMAC生成関数を使ってMAC値tと呼ばれる値を作り、データmと一緒にMAC値tをボブに送る
3.検証: 共有しておいた秘密鍵sと受け取ったデータmからMAC生成関数を使ってMAC値tを計算する
       L MAC値tが一致していればデータmを正常に受信できたとして受理(accept)、そうでなければ不正としてreject