[유니티/작업] ZXinq + SHA256 + QR코드 대량 생성기 구현/만들기 - 3

2022. 9. 19. 15:53·유니티/작업

[해당 프로젝트 깃허브]

https://github.com/taehuuun/SHA-QR-Gererator.git

 

GitHub - taehuuun/SHA-QR-Gererator: Generate data encrypted with SHA value as QR code

Generate data encrypted with SHA value as QR code. Contribute to taehuuun/SHA-QR-Gererator development by creating an account on GitHub.

github.com

 

이번에는 그동안 구현했던 기능들을 종합하여, QR코드를 대량 생산/저장할 것입니다.

 

전까지 만들었던 코드들은 유틸의 성격이 강하여 생성기를 분류하여 인터페이스를 제작하려고 합니다.

난이도 자체는 응용만 하면 되는 거라 오히려 관리하기 편하다고 생각하였습니다.

 

우선, UI 인터페이스를 잡아줍니다.

따로 디자인 같은 건 배우지 않아서 기본 UGUI로 대강 꾸며줍니다.

상단은 현재 작업 중인 파일 이름 (결과 값), 왼쪽은 생성된 QR 미리 보기 및 상태

오른쪽은 입력될 데이터와 생성수 저장기능이 포함되어 있습니다.

 

진짜 대충 디자인한...

 

기능 구현을 우선하여 코드를 짜서 그다지 효율적이지 못한 코드가 되긴 했습니다..ㅎㅎㅎ..

추후에 좀 더 효율적으로 작동하도록 수정해야 할 거 같습니다ㅠㅠ

 

핵심적인 기능 코드는 몇 부분 안됩니다.

 

1. QR코드를 생산하는 코드

보시면 아시겠지만 핵심적인 코드는 전 글에서 모두 구현하였기에 이런 식으로 사용하기만 하면 됩니다.

CryptoQR.EncryptSHA(type + modelID + curGenCnt.ToString());
private IEnumerator Gernerate()
{
    while(isActive)
    {
        // QRCode 생성
        curGenCnt++;
        string sha = CryptoQR.EncryptSHA(type + modelID + curGenCnt.ToString());

        // 생성된 QRCode를 Texture2D형태로 변수 할당 및 미리보기 이미지 변경
        Texture2D newQRCode = CryptoQR.CreateQRCode(sha);
        qrPreivew.texture = newQRCode;

        // 현재 SHA데이터와 QR코드를 리스트에 추가
        genQRCodes.Add(newQRCode);
        shaDatas.Add(sha);

        // 진행 상황을 업데이트
        float percent = ((float)curGenCnt / (float)maxGenCnt) * 100;
        Debug.Log(percent);
        topFileNameTxt.text = $"{type}.{sha}";
        curWorkStateTxt.text = $"{curGenCnt} / {maxGenCnt} ({percent.ToString("0.##")}%)";
        progressBarImg.fillAmount = percent * 0.01f;

        if (curGenCnt >= maxGenCnt)
        {
            Debug.Log("생성 완료");
            isActive = false;
            // Input UI를 활성화 상태로 전환
            InputActive(isActive);

            // 현재 선택한 QR코드 미리보기 인덱스를 0으로 설정
            curSelIdx = 1;
            curGenCnt = 0;

            // 0번째 QR코드를 미리보기 이미지로 변경
            qrPreivew.texture = genQRCodes[curSelIdx];

            // 생성된 QR코드 리스트의 갯수가 1보다 클경우 다음 선택버튼 활성화.
            prevBtn.interactable = false;
            nextBtn.interactable = genQRCodes.Count > 1;

            // 위와 동일 Save버튼에 적용됨.
            saveBtn.interactable = true;
            saveAllBtn.interactable = genQRCodes.Count > 1;

            curWorkStateTxt.text = $"{curSelIdx} / {maxGenCnt}";
            progressBarImg.fillAmount = 1 / (float)maxGenCnt;
            onOffBtnTxt.text = "Start";

            break;
        }

        yield return new WaitForFixedUpdate();
    }
}

 

2. 생성된 이미지를 저장하는 코드

저는 단일 저장과 전체저장 기능을 넣었는데 반복문에 차이일 뿐 동일합니다.

    public void SaveBtn()
    {
        CryptoQR.Save(genQRCodes[curSelIdx],pathStr+ @"\" + type, $"{type}.{shaDatas[curSelIdx]}");
    }

 

[테스트 영상]

https://youtu.be/B6 SBPpCwkJQ

 

전체 코드입니다.

더보기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class UI : MonoBehaviour
{
    [Header("Top")]
    [SerializeField] private TMP_Text topFileNameTxt;
    [SerializeField] private TMP_Text onOffBtnTxt;

    [Header("Main")]
    [SerializeField] private RawImage qrPreivew;
    [SerializeField] private Image progressBarImg;
    [SerializeField] private Button saveBtn;
    [SerializeField] private Button saveAllBtn;
    [SerializeField] private Button prevBtn;
    [SerializeField] private Button nextBtn;
    [SerializeField] private TMP_InputField typeInput;
    [SerializeField] private TMP_InputField modelIDInput;
    [SerializeField] private TMP_InputField genCountInput;
    [SerializeField] private TMP_Text curWorkStateTxt;

    [Header("Variable")]
    [SerializeField] private bool isActive;
    [SerializeField] private int curGenCnt;
    [SerializeField] private int maxGenCnt;
    [SerializeField] private string type;
    [SerializeField] private string modelID;
    [SerializeField] private string curSHAVal;
    [SerializeField] private string pathStr;

    [SerializeField] private List<Texture2D> genQRCodes = new List<Texture2D>();
    [SerializeField] private List<string> shaDatas = new List<string>();
    [SerializeField] private int curSelIdx = 1;

    private const int MAX_COUNT = 10000;
    

    #region Private Func

    private void Start()
    {
        // 최초 실행시
        Init();
    }

    /// <summary>
    /// 초기 변수 값들을 세팅하는 함수
    /// </summary>
    private void Init()
    {
        topFileNameTxt.text = "";
        typeInput.text = "";
        modelIDInput.text = "";
        genCountInput.text = "";

        isActive = false;
        curGenCnt = 0;
        prevBtn.interactable = false;
        nextBtn.interactable = false;
        saveAllBtn.interactable = false;
        saveBtn.interactable = false;
        progressBarImg.fillAmount = 0f;
    }

    private void InputActive(bool active)
    {
        typeInput.interactable = !active;
        modelIDInput.interactable = !active;
        genCountInput.interactable = !active;
    }

    private void SetVariable()
    {
        maxGenCnt = int.Parse(genCountInput.text);
        type = typeInput.text;
        modelID = modelIDInput.text;
        progressBarImg.fillAmount = 0f;
    }

    /// <summary>
    /// 입력 값이 필요한 UI, 변수값의 유효성을 체크하는 함수
    /// </summary>
    /// <returns></returns>
    private bool IsUIValidValue()
    {
        if(typeInput.text == "" || modelIDInput.text == "" || genCountInput.text =="")
        {
            Debug.LogError($"빈값을 입력 하셨습니다.");
            return false;             
        }

        if(int.Parse(genCountInput.text) > MAX_COUNT)
        {
            Debug.LogError($"생성 가능 최대치는 {MAX_COUNT} 입니다.");
            return false; 
        }
        return true;
    }

    private void ChangeSelect()
    {
        prevBtn.interactable = curSelIdx > 1;
        nextBtn.interactable = curSelIdx < genQRCodes.Count;

        qrPreivew.texture = genQRCodes[curSelIdx-1];
        topFileNameTxt.text = $"{type}.{shaDatas[curSelIdx-1]}";
        curWorkStateTxt.text = $"{curSelIdx} / {genQRCodes.Count}";
        progressBarImg.fillAmount = (float)curSelIdx / (float)genQRCodes.Count;
    }

    /// <summary>
    /// 실질적인 생성동작을 하는 코루틴 함수
    /// </summary>
    /// <returns></returns>
    private IEnumerator Gernerate()
    {
        while(isActive)
        {
            // QRCode 생성
            curGenCnt++;
            string sha = CryptoQR.EncryptSHA(type + modelID + curGenCnt.ToString());
            
            // 생성된 QRCode를 Texture2D형태로 변수 할당 및 미리보기 이미지 변경
            Texture2D newQRCode = CryptoQR.CreateQRCode(sha);
            qrPreivew.texture = newQRCode;

            // 현재 SHA데이터와 QR코드를 리스트에 추가
            genQRCodes.Add(newQRCode);
            shaDatas.Add(sha);

            // 진행 상황을 업데이트
            float percent = ((float)curGenCnt / (float)maxGenCnt) * 100;
            Debug.Log(percent);
            topFileNameTxt.text = $"{type}.{sha}";
            curWorkStateTxt.text = $"{curGenCnt} / {maxGenCnt} ({percent.ToString("0.##")}%)";
            progressBarImg.fillAmount = percent * 0.01f;

            if (curGenCnt >= maxGenCnt)
            {
                Debug.Log("생성 완료");
                isActive = false;
                // Input UI를 활성화 상태로 전환
                InputActive(isActive);

                // 현재 선택한 QR코드 미리보기 인덱스를 0으로 설정
                curSelIdx = 1;
                curGenCnt = 0;

                // 0번째 QR코드를 미리보기 이미지로 변경
                qrPreivew.texture = genQRCodes[curSelIdx];

                // 생성된 QR코드 리스트의 갯수가 1보다 클경우 다음 선택버튼 활성화.
                prevBtn.interactable = false;
                nextBtn.interactable = genQRCodes.Count > 1;

                // 위와 동일 Save버튼에 적용됨.
                saveBtn.interactable = true;
                saveAllBtn.interactable = genQRCodes.Count > 1;

                curWorkStateTxt.text = $"{curSelIdx} / {maxGenCnt}";
                progressBarImg.fillAmount = 1 / (float)maxGenCnt;
                onOffBtnTxt.text = "Start";

                break;
            }

            yield return new WaitForFixedUpdate();
        }
    }

    #endregion

    #region Public Func
    
    /// <summary>
    /// 생성기 On/Off 함수
    /// </summary>
    public void OnOffClick()
    {
        isActive = !isActive;
        onOffBtnTxt.text = isActive ? "Stop" : "Start";

        InputActive(isActive);

        if(isActive)
        {
            genQRCodes.Clear();
            shaDatas.Clear();
            curGenCnt = 0;

            if(IsUIValidValue())
            {

                SetVariable();
                StartCoroutine(Gernerate());
            }
            else
            {
                isActive = false;
                InputActive(isActive);
            }
        }
    }

    public void PrevBtn()
    {
        if (curSelIdx > 1)
            curSelIdx--;
        
        ChangeSelect();
    }

    public void NextBtn()
    {
        if (curSelIdx < genQRCodes.Count)
            curSelIdx++;
        
        ChangeSelect();
    }

    public void SaveBtn()
    {
        CryptoQR.Save(genQRCodes[curSelIdx],pathStr+ @"\" + type, $"{type}.{shaDatas[curSelIdx]}");
    }

    public void SavelAllBtn()
    {
        for(int i = 0 ; i < maxGenCnt; i++)
        {
            CryptoQR.Save(genQRCodes[i],pathStr+ @"\" + type, $"{type}.{shaDatas[i]}");
        }
    }

    #endregion
}
저작자표시 변경금지 (새창열림)
'유니티/작업' 카테고리의 다른 글
  • [유니티/게임개발] 픽셀 리마인드(PixelRemind) - 갤러리 모드 추가 수정 및 코드 정리
  • [유니티/게임개발] 픽셀 리마인드(PixelRemind) - 픽셀 아트의 json데이터를 다이어트 시키기
  • [유니티/작업] ZXinq + SHA256 + QR코드 대량 생성기 구현/만들기 - 2
  • [유니티/작업] ZXinq + SHA256 + QR코드 대량 생성기 구현/만들기 -1
프로포폴
프로포폴
Unity 클라이언트 개발자가 운영 하는 개발 블로그 입니다
  • 프로포폴
    약파는개발자
    프로포폴
  • 전체
    오늘
    어제
    • 분류 전체보기 (67)
      • 유니티 (21)
        • 공부 (0)
        • 튜토리얼 (0)
        • 에셋 (3)
        • 문제 해결 (2)
        • 작업 (16)
      • 언리얼(Unreal) (1)
        • 문제 해결 (1)
      • 백준 (20)
        • 브론즈5 (Bronze V) (20)
      • 프로그래머스(Programmers) (23)
        • C# 풀이 (23)
      • C# (0)
        • 팁 (Tip) (0)
      • 컴퓨터 과학(CS) (2)
        • 알고리즘 (1)
        • 자료구조 (1)
  • 블로그 메뉴

    • 홈
    • 글쓰기
    • 태그
    • 유니티
    • 알고리즘
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    Bronze V
    C++
    baekjoon
    브론즈5
    백준
    CS
    탐색(Search)
    프로그래머스
    c#
    개발일지
    컴퓨터과학
    projecta
    프로그래머스_C#
    픽셀리마인드
    유니티
    프로그래머스_Lv.0
    SHA
    작업
    Unity
    알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
프로포폴
[유니티/작업] ZXinq + SHA256 + QR코드 대량 생성기 구현/만들기 - 3
상단으로

티스토리툴바