Wrote program for Day 19
This commit is contained in:
parent
ed0187db74
commit
4a71624acc
@ -65,7 +65,7 @@ We encourage you to share your progress and ask questions in the Discussions sec
|
||||
| Day #16 | [Nim Game](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-16_Nim-Game) | :white_check_mark: |
|
||||
| Day #17 | [Prison Break](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-17_Prison-Break) | :white_check_mark: |
|
||||
| Day #18 | [Unique Paths](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-18_Unique-Paths) | :white_check_mark: |
|
||||
| Day #19 | [URL Shortener](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-19_URL-Shortener) | :white_large_square: |
|
||||
| Day #19 | [URL Shortener](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-19_URL-Shortener) | :white_check_mark: |
|
||||
| Day #20 | [API Challenge](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-20_API-Challenge) | :white_large_square: |
|
||||
| Day #21 | [Random Maze Generator](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-03/Day-21_Random-Maze-Generator) | :white_large_square: |
|
||||
| Day #22 | [Marcio Mellos Challenge](https://github.com/LiveGray/100-Days-Of-Rust/tree/main/Week-04/Day-22_Marcio-Mellos-Challenge) | :white_large_square: |
|
||||
|
6
Week-03/Day-19_URL-Shortener/day19/Cargo.toml
Normal file
6
Week-03/Day-19_URL-Shortener/day19/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "day19"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
98
Week-03/Day-19_URL-Shortener/day19/src/lib.rs
Normal file
98
Week-03/Day-19_URL-Shortener/day19/src/lib.rs
Normal file
@ -0,0 +1,98 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
fn valid_url(url: &str) -> Result<(), &str> {
|
||||
if !url.starts_with("http://") && !url.starts_with("https://") {
|
||||
Err("URL should start with either http:// or https://")
|
||||
} else if url.contains(' ') {
|
||||
Err("URL should not contain spaces")
|
||||
} else if url.len() < 12 {
|
||||
Err("URL should be at least 12 characters long")
|
||||
} else if url.len() > 2048 {
|
||||
Err("URL should not be longer than 2048 characters")
|
||||
} else if url.contains('\n') {
|
||||
Err("URL should not contain newlines")
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn url_shortener(url: &str, custom: Option<String>, rng: Option<Rng>) -> Result<String, &str> {
|
||||
valid_url(url)?;
|
||||
|
||||
let domain = "https://shortener.rs/";
|
||||
|
||||
if let Some(custom) = custom {
|
||||
Ok(format!("{}{}", domain, custom))
|
||||
} else if let Some(mut rng) = rng {
|
||||
Ok(format!("{}{}", domain, rng.random_string()))
|
||||
} else {
|
||||
Err("Either custom or rng should be provided")
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Rng {
|
||||
seed: u128,
|
||||
}
|
||||
|
||||
impl Rng {
|
||||
pub fn new() -> Rng {
|
||||
let time_since_epoch = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Error in getting time")
|
||||
.as_millis();
|
||||
Rng {
|
||||
seed: time_since_epoch,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random_string(&mut self) -> String {
|
||||
let random_number = self.linear_congruent_generator(1103515245, 12345, 2u128.pow(31));
|
||||
let binding = random_number.to_string();
|
||||
let bytes = binding.as_bytes();
|
||||
let (bytes, padding) = Rng::split_bits(bytes);
|
||||
let alphabet =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".as_bytes();
|
||||
let mut result = String::new();
|
||||
for b in bytes {
|
||||
result.push(alphabet[b as usize] as char);
|
||||
}
|
||||
for _ in (0..padding).step_by(2) {
|
||||
result.push('=');
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn split_bits(bytes: &[u8]) -> (Vec<u8>, usize) {
|
||||
let mut bits = Vec::new();
|
||||
for &byte in bytes {
|
||||
for i in (0..8).rev() {
|
||||
bits.push((byte >> i) & 1);
|
||||
}
|
||||
}
|
||||
let mut result = Vec::new();
|
||||
let mut padding = 0;
|
||||
for chunk in bits.chunks(6) {
|
||||
let mut byte = 0;
|
||||
for (i, &bit) in chunk.iter().enumerate() {
|
||||
byte |= bit << (5 - i);
|
||||
}
|
||||
result.push(byte);
|
||||
if chunk.len() < 6 {
|
||||
padding = 6 - chunk.len();
|
||||
}
|
||||
}
|
||||
(result, padding)
|
||||
}
|
||||
|
||||
fn linear_congruent_generator(&mut self, a: u128, c: u128, m: u128) -> u128 {
|
||||
let result = (a * self.seed + c) % m;
|
||||
self.seed = result;
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Rng {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
45
Week-03/Day-19_URL-Shortener/day19/src/main.rs
Normal file
45
Week-03/Day-19_URL-Shortener/day19/src/main.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use day19::{url_shortener, Rng};
|
||||
use std::io::{self, Write};
|
||||
|
||||
fn main() {
|
||||
let rng = Rng::new();
|
||||
let mut buffer = String::new();
|
||||
|
||||
print!("Enter the URL to shorten: ");
|
||||
io::stdout().flush().expect("Failed to flush stdout");
|
||||
|
||||
io::stdin()
|
||||
.read_line(&mut buffer)
|
||||
.expect("Failed to read from stdin");
|
||||
|
||||
let url = buffer.trim().to_owned();
|
||||
buffer = String::new();
|
||||
|
||||
print!("Do you want to provide a custom short URL? (y/n): ");
|
||||
io::stdout().flush().expect("Failed to flush stdout");
|
||||
|
||||
io::stdin()
|
||||
.read_line(&mut buffer)
|
||||
.expect("Failed to read from stdin");
|
||||
|
||||
let short_url = if buffer.trim() == "y" {
|
||||
buffer = String::new();
|
||||
|
||||
print!("Enter the custom short URL: ");
|
||||
io::stdout().flush().expect("Failed to flush stdout");
|
||||
|
||||
io::stdin()
|
||||
.read_line(&mut buffer)
|
||||
.expect("Failed to read from stdin");
|
||||
|
||||
let custom = Some(buffer.trim().to_string());
|
||||
url_shortener(&url, custom, None)
|
||||
} else {
|
||||
url_shortener(&url, None, Some(rng))
|
||||
};
|
||||
|
||||
match short_url {
|
||||
Ok(short_url) => println!("Shortened URL: {}", short_url),
|
||||
Err(e) => eprintln!("Error: {}", e),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user