p,m = map(int, input().split())
res=[]
for i in range(p):
l,n =input().split()
l = int(l)
if(len(res)==0):
res.append([(l,n)])
continue
flag=True
for j in range(len(res)):
if len(res[j])==m:
continue
if abs(res[j][0][0]-l)<=10:
res[j].append((l,n))
flag = False
break
if flag:
res.append([(l,n)])
for i in res:
i.sort(key=lambda x: x[1])
if(len(i)==m):
print('Started!')
else:
print('Waiting!')
for l,n in i:
print(l,n)
def solution(dirs):
answer = 0
num = {'U':(0,1),'D':(0,-1),'R':(1,0),'L':(-1,0)}
res={}
visited = set()
x, y = 0, 0
for i in dirs:
nx, ny = x + num[i][0], y + num[i][1]
if -5 <= nx <= 5 and -5 <= ny <= 5:
if ((x, y), (nx, ny)) not in visited:
answer += 1
visited.add(((x, y), (nx, ny)))
visited.add(((nx, ny), (x, y)))
x, y = nx, ny
return answer
풀이
중복을 제외하고 방문한 선분을 체크하기
입력받는 문자열에 따라 이동하는 좌표값 딕셔너리를 구현.
입력에 따라서 x,y를 움직인다. -5 ~ 5의 범위는 넘어가면 continue 해준다,
set()에 이동좌표를 넣어서 만약 그 좌표가 존재하지 않으면 answer+=1해주고, 존재하면 중복한 값이라고 판단하고 넘어간다.
def changeStrToInt(time):
return int(time[0:2]) * 60 + int(time[3:])
def solution(book_time):
sort_time = sorted([[changeStrToInt(i[0]), changeStrToInt(i[1]) + 10] for i in book_time])
res = []
for i in sort_time:
if len(res)==0:
res.append(i)
continue
for j in range(len(res)):
if(i[0] >= res[j][1]):
res[j] = res[j]+i
break
else:
res.append(i)
return len(res)
풀이
빈틈없이 예약해서 최소의 방 개수를 구하자
문자열로 입력받은 시간을 분으로 그리고 int형으로 만들어주는 함수를 작성한다.
그 다음 변환한 시간을 바탕으로 정렬해준다
정렬한 시간을 바탕으로 res배열에 넣어준
res배열이 비어 있으면 바로 넣어준다.
res배열을 돌면서 각각의 res배열의 제일 마지막 시간이 현재 첫번째 시간보다 작으면 거기 넣어준다.
http의 보안버전은 효율적이고 이식성이 좋고, 관리가 쉬워야 하며, 현실 세계의 변화에 대한 적응력이 좋아야한다. 또한 사회와 정부의 요구사항에도 맞아야한다.
다음을 제공해주는 HTTP의 보안기술이 필요하다.
서버 인증 : 클라이언트는 자신이 위조된 서버가 아닌 진짜와 이야기하고 있음을 알 수 있어야함
클라이언트 인증 : 서버는 자신이 가짜가 아닌 진짜 사용자와 이야기하고 있음을 알 수 있어야 한다.
무결성 : 클라이언트와 서버는 데이터가 위조되는것을 방지해야한다.
암호화 : 클라이언트와 서버가 서로 안전하게 대화해야 한다.
효율 : 저렴한 클라이언트나 서버도 이용할 수 있도록 알고리즘은 충분히 빨라야 한다.
편재성(Ubiquity) : 프로토콜은 거의 모든 클라이언트와 서버에서 지원되어야 한다.
관리상 확장성 : 누구든 어디서든 즉각적인 보안 통신을 할 수 있어야 한다.
적응성 : 현재 알려진 최선의 보안 방법을 지원해야 한다.
사회적 생존성 : 사회의 문화적, 정치적 요구를 만족시켜야 한다.
HTTPS
http를 안전하게 만드는 방식 중에서 가장 인기 있는 것
보안 전송 계층을 통해 전송되는 http이다
모든 주류 브라우저와 서버에서 지원한다.
firefox, safari, chore, edge 등등
모든 http 요청과 응답 데이터는 네트워크로 보내지기 전에 암호화된다. https는 http의 하부에 “전송 레벨 암호 보안 계층”을 제공함으로써 동작. → 이 보안 계층은 안전 소켓 계층(SSL, Secure Sockets Layer)혹은 그를 계승한 전송 계층 보안(TLS, Transport Layer Security)을 이용하여 구현. → SSL과 TLS는 사실상 같기 때문에 SSL이라고 표기하기도 함
SSL : Netscape사에서 1995년에 만든 통신 프로토콜
TSL : SSL의 3.0버전을 가지고 Netscape가 개발에서 빠지며 국제 인터넷 표준화 기구 **IETF(Internet Engineering Task Force)**에서 만든 프로토콜 ⇒ 현재는 SSL 2.0 및 3.0이 전부 사용 중지, 사실상 TLS만 사용. ⇒ 또한 TLS 1.0과 1.1도 사용 중지 예정
![[123.png]] ![[765432.png]]
→ 대부분의 경우, tcp 입력/출력 호출을 ssl 호출로 대체하고, 몇가지의 설정만 바꿔주면 된다.
인코딩 및 디코딩 작업은 대부분 SSL 라이브러리 안에서 일어나기 때문에 http의 로직을 크게 변경할 필요가 없다. → 대부분의 경우, tcp 입력/출력 호출을 ssl 호출로 대체하고, 몇가지의 설정만 바꿔주면 된다.
암호(cipher)
암호 : 메시지를 인코딩하는 어떤 특정한 방법과 나중에 그 비밀 메세지를 디코딩하는 방법을 말함.
원본 메세지(텍스트 or 평문)에 암호를 적용하면 암호문이 된다.
역사상 최초의 암호 : 스키테일 암호
스키테일 암호
카이사르의 순환암호
메세지의 각 글자를 알파벳 순서상 세번 뒤의 글자로 바꾸는 방법 사용
순환암호
디지털 암호
디지털 시대로 넘어오면서 두가지의 변화
속도 및 기능에 대한 전폭적인 성장, 훨씬 더 복잡한 인코딩과 디코딩이 가능해짐
매우 큰 키를 지원하는 것이 가능해져 단일 암호 알고리즘으로 키의 값마다 다른 수조개의 암호 알고리즘을 만들어 낼 수 있게 됨.
평문 메세지 P, 인코딩 함수 E, 디지털 인코딩 키 e가 주어졌을 때 암호문 C를 생성할 수 있다. ![[62138761283.png]]
# docker hub에서 이미지 가져오기
docker pull ngrinder/controller
# 가져온 이미지로 실행하기
docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller --name controller -p 80:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller
agent 설치 및 실행
# docker hub에서 이미지 가져오기
docker pull ngrinder/agent
# 가져온 이미지로 실행하기
# 위에서 생성했던 controller와 연결
docker run -d --name agent1 --link controller:controller ngrinder/agent
도커 이미지를 저장하고 가져다 쓰기 위한 Object Storage와 Container Registry를 생성해준다.
Object Storage 생성
Object Storage 이용 신청
이용 신청 후 버킷 생성
이름 입력 후 설정 건드리지않고 “다음” 버튼 클릭 후 버킷 생성
Container Registry 생성
Container Registry로 이동 후 “레지스트리 생성” 클릭
이름 입력 및 생성한 Object Storage 넣은 후 생성
vite+react+typescript에서 Dockerfile 만들기
배포할 프로젝트 최상단에 nginx를 사용하여 배포하는 Dockerfile을 생성
(참고로 현재 배포에 사용하는 gihub repo가 client와 server둘다 있어서 프론트 코드는 /client에 들어가 있다.)
# 첫 번째 단계: 빌드 환경 구축
FROM node:lts-alpine as build-stage
WORKDIR /app
# 의존성 파일 복사 및 설치
# COPY [내 package.json 파일과 yarn.lock 파일의 경로] [복사할 위치]
COPY ./client/package.json ./client/yarn.lock ./
RUN yarn install && yarn global add typescript
# 소스 코드 복사
COPY ./client .
RUN ls -l
# 애플리케이션 빌드
RUN yarn build
# 두 번째 단계: Nginx를 사용하여 애플리케이션 서빙
FROM nginx:stable-alpine as production-stage
# 빌드된 파일을 Nginx 서버로 복사
COPY --from=build-stage /app/dist /usr/share/nginx/html
# 80 포트 노출
EXPOSE 80
# Nginx 실행
CMD ["nginx", "-g", "daemon off;"]
CLI로 container registry에 도커 이미지 build,push 하기
NCP container registry에 로그인하기 위해서는 마이페이지에서 인증키 생성이 필요하다.
마이페이지 - 계정관리 - 인증키관리 - 신규 API 인증키 생성 - Access Key ID, Secret Key가 각각 ID, PW로 로그인시 사용된다.
해당 repository에 접근하기 위해서는 로그인이 필요하다.
Registry URL은 Container Registry에서 생성한 레지스트리를 클릭하면 Public Endpoint가 있는데 그것을 사용해주면 된다.
docker login <CONTAINER_REGISTRY_URL>
다음을 입력하면 username과 password를 입력하라고 나오는데, 위에서 발급한 Access Key ID를 username으로, secret key를 password로 입력하면 된다.
도커 파일을 작성한 배포할 프로젝트의 최상단에서 다음 명령어를 쳐주면 build되고 push되어서 Container Regisrty에 반영된다.
ssh-keygen -t rsa -b 4069 -C {자신의 메일} -f "./my_key" -N ""
# rsa 방식으로 4096비트를 사용해서 생성한다.
생성 완료되면
Generating public/private rsa key pair.
Your identification has been saved in ./my_key
Your public key has been saved in ./my_key.pub
The key fingerprint is:
SHA256:[여러 문자] [입력한 메일 주소]
The key's randomart image is:
+---[RSA 4069]----+
|+O |
|++@+. . . |
|oo.+ + o + |
|=. o o + |
|E.. . .So |
|o* . .. |
|..* ..+. |
|.. o. o |
| .o . |
+----[SHA256]-----+
이런 메세지가 뜨면서 파일 두개가 생성된다. my_key와 my_key.pub이 생성되는데 .pub가 공개키, my_key 암호키 즉 쌍(pair)으로 생성된다.
생성한 키페어를 테라폼 파일에 등록한다.
# ec2.tf
resource "aws_key_pair" "ec2_key" {
key_name = "my_key"
public_key = "my_key.pub 안에 있는 내용 전부 붙여넣기" or file("./my_key.pub")
}
ec2.tf를 만들어 주고 위의 코드를 작성해서 생성한 키페어를 테라폼에서 사용할 수 있게 만들어준다.
ec2 생성
aws_instance를 사용해서 쉽게 생성할 수 있다.
#ec2.tf
resource "aws_instance" "real_ec2" {
ami = "ami-0ba5cd124d7a79612"
#ubuntu 20.04의 ami
instance_type = "t3.small"
security_groups = [aws_security_group.realPublicSG.id]
subnet_id = aws_subnet.realPublicSubnet.id
key_name = aws_key_pair.ec2_key.key_name
root_block_device { #볼륨 설정 가능
volume_size = 200
volume_type = "gp3"
}
tags ={ #이름 설정 가능
Name = "real_ec2"
}
}
인스턴스 타입을 설정할 수 있다.
ami의 경우 콘솔에서 ami검색을 통해 id를 확인할 수 있다.
작성완료 했으면 terraform plan 후 apply (apply는 실제 환경에 적용이기 때문에 자주하지 않더라고 plan은 자주해서 오류를 바로바로 잡아내자!)