Base64 인코더 및 디코더: 텍스트를 Base64로 변환
텍스트를 Base64로 인코딩하거나 Base64 문자열을 텍스트로 다시 디코딩하는 무료 온라인 도구입니다. 표준 및 URL 안전 Base64 인코딩을 지원하며 즉시 변환됩니다.
Base64 인코더/디코더
텍스트를 Base64 인코딩으로 변환하거나 그 반대로 변환합니다
문서
Base64 인코더 및 디코더
소개
Base64는 이진 데이터를 ASCII 문자열 형식으로 표현하는 이진-텍스트 인코딩 방식입니다. 이진 형식으로 저장된 데이터를 텍스트 콘텐츠만 안정적으로 지원하는 채널을 통해 전송할 수 있도록 설계되었습니다. Base64 인코딩은 이진 데이터를 안전하게 텍스트 기반 프로토콜을 통해 전송할 수 있도록 64개의 문자 집합으로 변환합니다(따라서 이름이 붙었습니다).
Base64 문자 집합은 다음으로 구성됩니다:
- 대문자 A-Z (26자)
- 소문자 a-z (26자)
- 숫자 0-9 (10자)
- 일반적으로 "+"와 "/"인 두 개의 추가 문자 (2자)
이 도구를 사용하면 텍스트를 Base64 형식으로 쉽게 인코딩하거나 Base64 문자열을 원래 텍스트로 디코딩할 수 있습니다. 이는 개발자, IT 전문가 및 텍스트 기반 채널을 통해 안전하게 전송해야 하는 데이터와 작업하는 모든 사람에게 특히 유용합니다.
Base64 인코딩 작동 방식
인코딩 과정
Base64 인코딩은 이진 데이터의 3바이트(24비트) 그룹을 4개의 Base64 문자로 변환하여 작동합니다. 이 과정은 다음 단계로 진행됩니다:
- 입력 텍스트를 이진 표현으로 변환합니다(ASCII 또는 UTF-8 인코딩 사용)
- 이진 데이터를 24비트(3바이트) 청크로 그룹화합니다
- 각 24비트 청크를 4개의 6비트 그룹으로 나눕니다
- 각 6비트 그룹을 해당 Base64 문자로 변환합니다
입력 길이가 3으로 나누어 떨어지지 않을 경우, 4:3 비율을 유지하기 위해 "=" 문자를 추가하여 패딩합니다.
수학적 표현
바이트 시퀀스 에 대해 해당 Base64 문자는 로 계산됩니다:
여기서 는 Base64 알파벳의 번째 문자를 나타냅니다.
디코딩 과정
Base64 디코딩은 인코딩 과정을 역으로 수행합니다:
- 각 Base64 문자를 6비트 값으로 변환합니다
- 이러한 6비트 값을 연결합니다
- 비트를 8비트 청크(바이트)로 그룹화합니다
- 각 바이트를 해당 문자로 변환합니다
패딩
인코딩할 바이트 수가 3으로 나누어 떨어지지 않을 경우 패딩이 적용됩니다:
- 바이트가 하나 남으면 두 개의 Base64 문자로 변환되고 "=="가 뒤에 추가됩니다
- 바이트가 두 개 남으면 세 개의 Base64 문자로 변환되고 "="가 뒤에 추가됩니다
예시
텍스트 "Hello"를 Base64로 인코딩해 보겠습니다:
- "Hello"의 ASCII 표현: 72 101 108 108 111
- 이진 표현: 01001000 01100101 01101100 01101100 01101111
- 6비트 청크로 그룹화: 010010 000110 010101 101100 011011 000110 1111
- 마지막 청크는 4비트만 있으므로 0으로 패딩합니다: 010010 000110 010101 101100 011011 000110 111100
- 십진수로 변환: 18, 6, 21, 44, 27, 6, 60
- Base64 알파벳에서 조회: S, G, V, s, b, G, 8
- 결과는 "SGVsbG8="입니다
입력 길이(5바이트)가 3으로 나누어 떨어지지 않기 때문에 끝에 "=" 패딩이 있는 점에 유의하십시오.
공식
Base64 인코딩 문자열의 길이를 계산하는 일반 공식은 다음과 같습니다:
여기서 는 천장 함수(가장 가까운 정수로 올림)를 나타냅니다.
사용 사례
Base64 인코딩은 다양한 애플리케이션에서 널리 사용됩니다:
-
이메일 첨부 파일: MIME(다목적 인터넷 메일 확장)는 이메일에서 이진 첨부 파일을 인코딩하는 데 Base64를 사용합니다.
-
데이터 URL: HTML, CSS 또는 JavaScript에서 작은 이미지, 글꼴 또는 기타 리소스를 직접 포함하는 데
data:
URL 스킴을 사용합니다. -
API 통신: JSON 페이로드 또는 기타 텍스트 기반 API 형식에서 이진 데이터를 안전하게 전송합니다.
-
텍스트 형식으로 이진 데이터 저장: 이진 데이터를 XML, JSON 또는 기타 텍스트 기반 형식에 저장해야 할 때.
-
인증 시스템: HTTP의 기본 인증은 Base64 인코딩을 사용합니다(보안이 아니라 인코딩을 위한 것입니다).
-
암호화: 다양한 암호화 프로토콜 및 시스템의 일부로, 종종 키 또는 인증서를 인코딩하는 데 사용됩니다.
-
쿠키 값: 쿠키에 저장할 복잡한 데이터 구조를 인코딩합니다.
대안
Base64는 널리 사용되지만 특정 상황에서는 더 적합한 대안이 있을 수 있습니다:
-
URL 안전 Base64: "+"와 "/" 대신 "-"와 "_"를 사용하여 URL 인코딩 문제를 피하는 변형입니다. URL에 포함될 데이터에 유용합니다.
-
Base32: 32자 집합을 사용하여 출력이 더 길어지지만 가독성이 더 좋고 대소문자를 구분하지 않습니다.
-
16진수 인코딩: 16진수로 간단하게 변환하여 크기가 두 배로 증가하지만 매우 간단하고 널리 지원됩니다.
-
이진 전송: 대용량 파일이나 효율성이 중요한 경우, 적절한 Content-Type 헤더가 있는 HTTP와 같은 직접 이진 전송 프로토콜이 더 바람직합니다.
-
압축 + Base64: 대량의 텍스트 데이터를 위해 인코딩하기 전에 압축하면 크기 증가를 완화할 수 있습니다.
-
JSON/XML 직렬화: 구조화된 데이터의 경우 Base64 인코딩보다 기본 JSON 또는 XML 직렬화를 사용하는 것이 더 적절할 수 있습니다.
역사
Base64 인코딩은 이진 데이터를 텍스트로 전송해야 했던 초기 컴퓨팅 및 통신 시스템에서 그 뿌리를 찾을 수 있습니다.
Base64의 공식 사양은 1987년 RFC 989의 일부로 처음 발표되었으며, 이는 개인 정보 보호 강화 메일(PEM)을 정의했습니다. 이후 RFC 1421(1993) 및 RFC 2045(1996, MIME의 일부)에서 업데이트되었습니다.
"Base64"라는 용어는 인코딩이 이진 데이터를 표현하기 위해 64개의 서로 다른 ASCII 문자를 사용한다는 사실에서 유래되었습니다. 이 64자 선택은 64가 2의 거듭제곱(2^6)이기 때문에 이진과 Base64 간의 변환이 효율적이도록 의도적으로 이루어졌습니다.
시간이 지나면서 여러 가지 Base64 변형이 등장했습니다:
- 표준 Base64: RFC 4648에 정의된 대로 A-Z, a-z, 0-9, +, / 및 =를 패딩으로 사용합니다.
- URL 안전 Base64: URL 인코딩 문제를 피하기 위해 -와 _를 사용하는 변형입니다.
- 파일 이름 안전 Base64: 파일 이름에 사용하기 위해 설계된 유사한 변형입니다.
- IMAP을 위한 수정된 Base64: IMAP 프로토콜에서 사용되는 특수 문자 집합이 다른 변형입니다.
30년이 넘는 시간이 지나도 Base64는 현대 컴퓨팅에서 여전히 중요한 도구로 남아 있으며, 특히 JSON과 같은 텍스트 기반 데이터 형식에 크게 의존하는 웹 애플리케이션과 API의 증가와 함께 더욱 그러합니다.
코드 예제
다양한 프로그래밍 언어에서 Base64 인코딩 및 디코딩의 예는 다음과 같습니다:
1// JavaScript Base64 인코딩/디코딩
2function encodeToBase64(text) {
3 return btoa(text);
4}
5
6function decodeFromBase64(base64String) {
7 try {
8 return atob(base64String);
9 } catch (e) {
10 throw new Error("유효하지 않은 Base64 문자열");
11 }
12}
13
14// 예시 사용
15const originalText = "Hello, World!";
16const encoded = encodeToBase64(originalText);
17console.log("인코딩된:", encoded); // SGVsbG8sIFdvcmxkIQ==
18
19try {
20 const decoded = decodeFromBase64(encoded);
21 console.log("디코딩된:", decoded); // Hello, World!
22} catch (error) {
23 console.error(error.message);
24}
25
1# Python Base64 인코딩/디코딩
2import base64
3
4def encode_to_base64(text):
5 # 문자열을 바이트로 변환한 후 인코딩
6 text_bytes = text.encode('utf-8')
7 base64_bytes = base64.b64encode(text_bytes)
8 return base64_bytes.decode('utf-8')
9
10def decode_from_base64(base64_string):
11 try:
12 # Base64 문자열을 바이트로 변환한 후 디코딩
13 base64_bytes = base64_string.encode('utf-8')
14 text_bytes = base64.b64decode(base64_bytes)
15 return text_bytes.decode('utf-8')
16 except Exception as e:
17 raise ValueError(f"유효하지 않은 Base64 문자열: {e}")
18
19# 예시 사용
20original_text = "Hello, World!"
21encoded = encode_to_base64(original_text)
22print(f"인코딩된: {encoded}") # SGVsbG8sIFdvcmxkIQ==
23
24try:
25 decoded = decode_from_base64(encoded)
26 print(f"디코딩된: {decoded}") # Hello, World!
27except ValueError as e:
28 print(e)
29
1// Java Base64 인코딩/디코딩
2import java.util.Base64;
3import java.nio.charset.StandardCharsets;
4
5public class Base64Example {
6 public static String encodeToBase64(String text) {
7 byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
8 byte[] encodedBytes = Base64.getEncoder().encode(textBytes);
9 return new String(encodedBytes, StandardCharsets.UTF_8);
10 }
11
12 public static String decodeFromBase64(String base64String) {
13 try {
14 byte[] base64Bytes = base64String.getBytes(StandardCharsets.UTF_8);
15 byte[] decodedBytes = Base64.getDecoder().decode(base64Bytes);
16 return new String(decodedBytes, StandardCharsets.UTF_8);
17 } catch (IllegalArgumentException e) {
18 throw new IllegalArgumentException("유효하지 않은 Base64 문자열: " + e.getMessage());
19 }
20 }
21
22 public static void main(String[] args) {
23 String originalText = "Hello, World!";
24 String encoded = encodeToBase64(originalText);
25 System.out.println("인코딩된: " + encoded); // SGVsbG8sIFdvcmxkIQ==
26
27 try {
28 String decoded = decodeFromBase64(encoded);
29 System.out.println("디코딩된: " + decoded); // Hello, World!
30 } catch (IllegalArgumentException e) {
31 System.err.println(e.getMessage());
32 }
33 }
34}
35
1<?php
2// PHP Base64 인코딩/디코딩
3function encodeToBase64($text) {
4 return base64_encode($text);
5}
6
7function decodeFromBase64($base64String) {
8 $decoded = base64_decode($base64String, true);
9 if ($decoded === false) {
10 throw new Exception("유효하지 않은 Base64 문자열");
11 }
12 return $decoded;
13}
14
15// 예시 사용
16$originalText = "Hello, World!";
17$encoded = encodeToBase64($originalText);
18echo "인코딩된: " . $encoded . "\n"; // SGVsbG8sIFdvcmxkIQ==
19
20try {
21 $decoded = decodeFromBase64($encoded);
22 echo "디코딩된: " . $decoded . "\n"; // Hello, World!
23} catch (Exception $e) {
24 echo "오류: " . $e->getMessage() . "\n";
25}
26?>
27
1// C# Base64 인코딩/디코딩
2using System;
3using System.Text;
4
5class Base64Example
6{
7 public static string EncodeToBase64(string text)
8 {
9 byte[] textBytes = Encoding.UTF8.GetBytes(text);
10 return Convert.ToBase64String(textBytes);
11 }
12
13 public static string DecodeFromBase64(string base64String)
14 {
15 try
16 {
17 byte[] base64Bytes = Convert.FromBase64String(base64String);
18 return Encoding.UTF8.GetString(base64Bytes);
19 }
20 catch (FormatException)
21 {
22 throw new FormatException("유효하지 않은 Base64 문자열");
23 }
24 }
25
26 static void Main()
27 {
28 string originalText = "Hello, World!";
29 string encoded = EncodeToBase64(originalText);
30 Console.WriteLine($"인코딩된: {encoded}"); // SGVsbG8sIFdvcmxkIQ==
31
32 try
33 {
34 string decoded = DecodeFromBase64(encoded);
35 Console.WriteLine($"디코딩된: {decoded}"); // Hello, World!
36 }
37 catch (FormatException e)
38 {
39 Console.WriteLine($"오류: {e.Message}");
40 }
41 }
42}
43
1# Ruby Base64 인코딩/디코딩
2require 'base64'
3
4def encode_to_base64(text)
5 Base64.strict_encode64(text)
6end
7
8def decode_from_base64(base64_string)
9 begin
10 Base64.strict_decode64(base64_string)
11 rescue ArgumentError => e
12 raise "유효하지 않은 Base64 문자열: #{e.message}"
13 end
14end
15
16# 예시 사용
17original_text = "Hello, World!"
18encoded = encode_to_base64(original_text)
19puts "인코딩된: #{encoded}" # SGVsbG8sIFdvcmxkIQ==
20
21begin
22 decoded = decode_from_base64(encoded)
23 puts "디코딩된: #{decoded}" # Hello, World!
24rescue StandardError => e
25 puts "오류: #{e.message}"
26end
27
1// Go Base64 인코딩/디코딩
2package main
3
4import (
5 "encoding/base64"
6 "fmt"
7)
8
9func encodeToBase64(text string) string {
10 return base64.StdEncoding.EncodeToString([]byte(text))
11}
12
13func decodeFromBase64(base64String string) (string, error) {
14 bytes, err := base64.StdEncoding.DecodeString(base64String)
15 if err != nil {
16 return "", fmt.Errorf("유효하지 않은 Base64 문자열: %v", err)
17 }
18 return string(bytes), nil
19}
20
21func main() {
22 originalText := "Hello, World!"
23 encoded := encodeToBase64(originalText)
24 fmt.Println("인코딩된:", encoded) // SGVsbG8sIFdvcmxkIQ==
25
26 decoded, err := decodeFromBase64(encoded)
27 if err != nil {
28 fmt.Println("오류:", err)
29 } else {
30 fmt.Println("디코딩된:", decoded) // Hello, World!
31 }
32}
33
1// Swift Base64 인코딩/디코딩
2import Foundation
3
4func encodeToBase64(_ text: String) -> String? {
5 if let data = text.data(using: .utf8) {
6 return data.base64EncodedString()
7 }
8 return nil
9}
10
11func decodeFromBase64(_ base64String: String) -> String? {
12 if let data = Data(base64Encoded: base64String) {
13 return String(data: data, encoding: .utf8)
14 }
15 return nil
16}
17
18// 예시 사용
19let originalText = "Hello, World!"
20if let encoded = encodeToBase64(originalText) {
21 print("인코딩된: \(encoded)") // SGVsbG8sIFdvcmxkIQ==
22
23 if let decoded = decodeFromBase64(encoded) {
24 print("디코딩된: \(decoded)") // Hello, World!
25 } else {
26 print("오류: Base64 문자열을 디코딩할 수 없습니다")
27 }
28} else {
29 print("오류: 텍스트를 인코딩할 수 없습니다")
30}
31
1' Excel VBA Base64 인코딩/디코딩
2' 참고: Microsoft XML, v6.0에 대한 참조가 필요합니다
3Function EncodeToBase64(text As String) As String
4 Dim xmlObj As Object
5 Set xmlObj = CreateObject("MSXML2.DOMDocument")
6
7 Dim xmlNode As Object
8 Set xmlNode = xmlObj.createElement("b64")
9
10 xmlNode.DataType = "bin.base64"
11 xmlNode.nodeTypedValue = StrConv(text, vbFromUnicode)
12
13 EncodeToBase64 = xmlNode.text
14
15 Set xmlNode = Nothing
16 Set xmlObj = Nothing
17End Function
18
19Function DecodeFromBase64(base64String As String) As String
20 On Error GoTo ErrorHandler
21
22 Dim xmlObj As Object
23 Set xmlObj = CreateObject("MSXML2.DOMDocument")
24
25 Dim xmlNode As Object
26 Set xmlNode = xmlObj.createElement("b64")
27
28 xmlNode.DataType = "bin.base64"
29 xmlNode.text = base64String
30
31 DecodeFromBase64 = StrConv(xmlNode.nodeTypedValue, vbUnicode)
32
33 Set xmlNode = Nothing
34 Set xmlObj = Nothing
35 Exit Function
36
37ErrorHandler:
38 DecodeFromBase64 = "오류: 유효하지 않은 Base64 문자열"
39End Function
40
41' 워크시트에서 사용:
42' =EncodeToBase64("Hello, World!")
43' =DecodeFromBase64("SGVsbG8sIFdvcmxkIQ==")
44
1# R Base64 인코딩/디코딩
2# 'base64enc' 패키지가 필요합니다
3# install.packages("base64enc")
4library(base64enc)
5
6encode_to_base64 <- function(text) {
7 # 텍스트를 원시 바이트로 변환한 후 인코딩
8 text_raw <- charToRaw(text)
9 base64_encoded <- base64encode(text_raw)
10 return(rawToChar(base64_encoded))
11}
12
13decode_from_base64 <- function(base64_string) {
14 tryCatch({
15 # Base64 문자열을 원시로 변환한 후 디코딩
16 base64_raw <- charToRaw(base64_string)
17 decoded_raw <- base64decode(base64_raw)
18 return(rawToChar(decoded_raw))
19 }, error = function(e) {
20 stop(paste("유효하지 않은 Base64 문자열:", e$message))
21 })
22}
23
24# 예시 사용
25original_text <- "Hello, World!"
26encoded <- encode_to_base64(original_text)
27cat("인코딩된:", encoded, "\n") # SGVsbG8sIFdvcmxkIQ==
28
29tryCatch({
30 decoded <- decode_from_base64(encoded)
31 cat("디코딩된:", decoded, "\n") # Hello, World!
32}, error = function(e) {
33 cat("오류:", e$message, "\n")
34})
35
1% MATLAB Base64 인코딩/디코딩
2function demo_base64()
3 originalText = 'Hello, World!';
4
5 % 인코딩
6 encoded = encode_to_base64(originalText);
7 fprintf('인코딩된: %s\n', encoded); % SGVsbG8sIFdvcmxkIQ==
8
9 % 디코딩
10 try
11 decoded = decode_from_base64(encoded);
12 fprintf('디코딩된: %s\n', decoded); % Hello, World!
13 catch e
14 fprintf('오류: %s\n', e.message);
15 end
16end
17
18function encoded = encode_to_base64(text)
19 % 텍스트를 uint8 배열로 변환한 후 인코딩
20 bytes = uint8(text);
21 encoded = base64encode(bytes);
22end
23
24function decoded = decode_from_base64(base64String)
25 try
26 % Base64 문자열을 uint8 배열로 디코딩
27 bytes = base64decode(base64String);
28 decoded = char(bytes);
29 catch
30 error('유효하지 않은 Base64 문자열');
31 end
32end
33
1// C Base64 인코딩/디코딩 OpenSSL 사용
2#include <stdio.h>
3#include <string.h>
4#include <openssl/bio.h>
5#include <openssl/evp.h>
6#include <openssl/buffer.h>
7#include <stdint.h>
8
9char* encode_to_base64(const char* input) {
10 BIO *bio, *b64;
11 BUF_MEM *bufferPtr;
12
13 b64 = BIO_new(BIO_f_base64());
14 bio = BIO_new(BIO_s_mem());
15 bio = BIO_push(b64, bio);
16
17 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
18 BIO_write(bio, input, strlen(input));
19 BIO_flush(bio);
20 BIO_get_mem_ptr(bio, &bufferPtr);
21
22 char* result = (char*)malloc(bufferPtr->length + 1);
23 memcpy(result, bufferPtr->data, bufferPtr->length);
24 result[bufferPtr->length] = '\0';
25
26 BIO_free_all(bio);
27
28 return result;
29}
30
31char* decode_from_base64(const char* input) {
32 BIO *bio, *b64;
33 size_t length = strlen(input);
34 char* buffer = (char*)malloc(length);
35
36 b64 = BIO_new(BIO_f_base64());
37 bio = BIO_new_mem_buf(input, -1);
38 bio = BIO_push(b64, bio);
39
40 BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
41 int decoded_length = BIO_read(bio, buffer, length);
42
43 if (decoded_length <= 0) {
44 free(buffer);
45 BIO_free_all(bio);
46 return NULL; // 유효하지 않은 Base64 입력
47 }
48
49 buffer[decoded_length] = '\0';
50
51 BIO_free_all(bio);
52
53 return buffer;
54}
55
56int main() {
57 const char* original_text = "Hello, World!";
58
59 char* encoded = encode_to_base64(original_text);
60 printf("인코딩된: %s\n", encoded); // SGVsbG8sIFdvcmxkIQ==
61
62 char* decoded = decode_from_base64(encoded);
63 if (decoded) {
64 printf("디코딩된: %s\n", decoded); // Hello, World!
65 free(decoded);
66 } else {
67 printf("오류: 유효하지 않은 Base64 문자열\n");
68 }
69
70 free(encoded);
71
72 return 0;
73}
74
1// Rust Base64 인코딩/디코딩
2use base64::{encode, decode};
3use std::str;
4
5fn encode_to_base64(text: &str) -> String {
6 encode(text)
7}
8
9fn decode_from_base64(base64_string: &str) -> Result<String, String> {
10 match decode(base64_string) {
11 Ok(bytes) => {
12 match str::from_utf8(&bytes) {
13 Ok(text) => Ok(text.to_string()),
14 Err(e) => Err(format!("유효하지 않은 UTF-8 시퀀스: {}", e))
15 }
16 },
17 Err(e) => Err(format!("유효하지 않은 Base64 문자열: {}", e))
18 }
19}
20
21fn main() {
22 let original_text = "Hello, World!";
23 let encoded = encode_to_base64(original_text);
24 println!("인코딩된: {}", encoded); // SGVsbG8sIFdvcmxkIQ==
25
26 match decode_from_base64(&encoded) {
27 Ok(decoded) => println!("디코딩된: {}", decoded), // Hello, World!
28 Err(e) => println!("오류: {}", e)
29 }
30}
31
엣지 케이스 및 고려 사항
Base64 인코딩 및 디코딩 작업을 수행할 때 다음과 같은 중요한 고려 사항을 염두에 두십시오:
-
유니코드 및 비 ASCII 문자: 비 ASCII 문자가 포함된 텍스트를 인코딩할 때는 Base64 인코딩 전에 적절한 문자 인코딩(일반적으로 UTF-8)을 보장해야 합니다.
-
패딩: 표준 Base64는 출력 길이가 4의 배수가 되도록 "=" 문자를 사용하여 패딩합니다. 일부 구현은 패딩을 생략할 수 있지만, 이는 호환성 문제를 일으킬 수 있습니다.
-
줄 바꿈: 전통적인 Base64 구현은 가독성을 위해 줄 바꿈(일반적으로 76자마다)을 삽입하지만, 현대 애플리케이션은 종종 이를 생략합니다.
-
URL 안전 Base64: 표준 Base64는 "+" 및 "/" 문자를 사용하는데, 이는 URL에서 특별한 의미를 가집니다. URL 맥락에서는 "-" 및 "_"를 사용하는 URL 안전 Base64를 사용해야 합니다.
-
공백: 디코딩 시 일부 구현은 관대하게 공백을 무시하지만, 다른 구현은 정확한 입력을 요구합니다.
-
크기 증가: Base64 인코딩은 데이터 크기를 약 33% 증가시킵니다(3바이트 입력당 4바이트 출력).
-
성능: Base64 인코딩/디코딩은 매우 큰 데이터에 대해 계산 집약적일 수 있습니다. 대용량 파일의 경우 스트리밍 접근 방식을 고려하십시오.
참고 문헌
피드백
피드백 토스트를 클릭하여 이 도구에 대한 피드백을 시작하세요.
관련 도구
귀하의 작업 흐름에 유용할 수 있는 더 많은 도구를 발견하세요.