diff --git a/ReadMe.md b/ReadMe.md index 44d2376..631addd 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -15,6 +15,6 @@ - [x] 개발 환경 구축 - [x] DB 설계 및 Entity 구현 - [x] HTTP(HTTPS) URL 검증 구현 -- [ ] URL 단축 알고리즘 구현 +- [x] URL 단축 알고리즘 구현 - [ ] URL 단축 저장 및 조회 기능 구현 - [ ] 테스트 및 배포 \ No newline at end of file diff --git a/src/main/java/be/gyu/urlShortener/service/MainService.java b/src/main/java/be/gyu/urlShortener/service/MainService.java new file mode 100644 index 0000000..b574d81 --- /dev/null +++ b/src/main/java/be/gyu/urlShortener/service/MainService.java @@ -0,0 +1,82 @@ +package be.gyu.urlShortener.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import be.gyu.urlShortener.entity.UrlMap; +import be.gyu.urlShortener.repository.UrlMapRepository; + +import java.time.LocalDateTime; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import io.seruco.encoding.base62.Base62; + +@Service +public class MainService { + @Autowired + private UrlMapRepository urlMapRepository; + + // HTTP(S) URL 검증 패턴식 + private final String urlRegPattern="^((http|https):\\/\\/)?([a-z0-9-]{2,}\\.[a-z]{2,}|([0-9]{1,3}\\.){3}[0-9]{1,3})[\\w.\\/가-힣\\-\\ ?=&:]*"; + // Base62 Encoder Instance 생성 및 호출 + private Base62 base62=Base62.createInstance(); + + // HTTP(S) URL 검증 메소드 + public boolean validOriginalUrl(String url){ + return url.matches(urlRegPattern); + } + + // URL 단축 메소드 + public String createUrlShort(String url){ + // SHA-256 Hashing을 위해 Instance 생성 및 호출 + MessageDigest md; + try{ + md=MessageDigest.getInstance("sha256"); + }catch(NoSuchAlgorithmException e){ + e.printStackTrace(); + throw new RuntimeException(e); + } + + // DB에 저장하기 위해 Entity 객체 정의 + UrlMap urlMap=UrlMap.builder() + .urlMapOriginal(url) + .urlMapShort("") + .urlMapIsActive(false) + .urlMapClick(0l) + .urlMapCreatedAt(LocalDateTime.now()) + .urlMapUpdatedAt(LocalDateTime.now()) + .build(); + + // DB에 저장 - 초기 저장 (단축 URL은 빈 값으로 우선 저장) + urlMapRepository.save(urlMap); + + // 고유 값 생성 + // 고유한 값은 DB의 ID 값 + 현재 시간을 결합한 문자열을 SHA-256으로 해싱한 후, + // Base62로 인코딩 진행 + long id=urlMap.getUrlMapId(); + String urlMapIdString=String.format("%011d",id); + String nowDateTimeString=LocalDateTime.now().toString(); + String result=urlMapIdString+nowDateTimeString; + + // Base62 Encoding + byte[] barr=base62.encode(md.digest(result.getBytes())); + StringBuilder sb=new StringBuilder(); + for(byte b : barr){ + sb.append(String.format("%c",b)); + } + + // 해싱 및 인코딩된 문장을 7자리 추출하여 저장 + String shortResult=sb.toString().substring(0,7); + urlMap=urlMap.toBuilder() + .urlMapShort(shortResult) + .build(); + + // 최종 저장 - 단축된 URL도 포함하여 저장 + // (기존 데이터에 Update하는 방법으로 저장) + urlMapRepository.save(urlMap); + + // 단축된 URL 반환 + return shortResult; + } +}