다양한 문자 조합을 이용한 카운팅 구하기

by 조쉬 posted Dec 09, 2016
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄

 다양한 문자를 조합하여 ID 를 만들며 카운팅 수만큼 증가하여 문자열로 반환한다.

* 제목을 정하기 정말 힘들군요... 의미 전달이 전혀되지 않을 것 같네요;;

다양한 문자을 배열로 조합하여, 카운팅됨에 따라 오름차순 문자열을 완성하여 반환한다.

문자열 ID를 이용할 경우의 장점.

1. 숫자형이 아닌 문자열로 구현된 ID 및 코드를 구현할 때.
2. 쉽게 알아보기 힘든 코드를 구현할 때.
(숫자형으로 할 경우 GET 방식으로 쉽게 페이지를 호출할 수 있는 문제가 있다. 싸**드 같은 경우 비공개나 일촌공개로 설정된 사진도 날짜만 잘 조합하면 쉽게 열수 있는 문제가 있었다. 아마도 지금은 막았겠지만 또한 인젝션해킹이 문자열보다 인지하기 편해서 쉽게 이루어진다.)

3. 0~9 까지만 표현할 수 있는 숫자 조합보다 몇배 자료를 구현할 수 있다.

로직은 다음과 같다. 임의의 배열을 만들어 놓고, [a,z,s,e,1] 0 => a , 1 => z , 2 => s 각 문자의 실제 숫자값은 배열의 순서가 된다.
012 => azs 가 되는 것이다. 오름차값을 1을 할 경우 다음의 값은 aze 가 된다. 숫자,영문소문자,영문대문자 를 조합할 경우 한자리 표시를 61개까지 구성할 수 있다. 0~9 숫자로 할때에 비해 6배나 많은 량이다.

초기값은 원하는 자리수 만큼 정해줘야 한다. aaaa 가 4자리의 초기값이 되는 것이다. 다음 값은 aaaz 가 된다.
오름값은 생성하지 않을 경우 1111 일때 다음 값을 생성할때 오류가 발생한다.

소스 코드는 가장 많이 사용되는 자바스크립트로 개발하였고, 다시 자바로 컴버전하였다. 언어에 맞게 소스수정만 하면 어느 언어든 사용할 수 있을 것 이다. 자바는 http://commons.apache.org/lang 라이브러리의 ArrayUtils 사용했다.

* 예외처리는 직접 해주세요;;

 자바스크립트 소스


/**
  * programmed by Seok Kyun. Choi. (최석균)
  * http://syaku.tistory.com
  */
 var number = ['0','1','2','3','4','5','7','8','9'];
 var alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
 var ALPHABET = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
 var all = number.concat(alphabet).concat(ALPHABET);

 function string2integer(str) {
   var total = all.length;
   var chr = str.length;
   var data = [ ];

   for (var c = (chr-1); c >= 0; c--) {
     var s = str[c]; // 인수 문자

    for (var i = 0; i < total; i++) {
       var key = all[i];

       if (key == s) { data.push(i); } // 인수의 문자와 all 배열의 문자가 일치할 경우 배열에 삽입.
     }

   }

   return data; // 배열리턴

}

function integer2string(ar,num,is) {

   var total = all.length;
   var count = ar.length;
   var is_key = false;
   var data = [ ];

   for (var i = 0; i < count; i++) {
     var key = ar[i];

     if (i ==0) { // 첫번째 배열에 인수의 값을 더함.
       key = key + num;
     }

     if (is_key) { // 올림수 여부
      key = key + 1;
     }

     if (key >= total) {
       key = key - total;
      is_key = true;
     } else {
       is_key = false;
     }

    data[(count-1)-i] = all[key]; // 역순으로 배열 생성.

   }

   if (is_key) { // 마지막 루프에서 올림수가 있을 경우 한자리 추가
    if (is == false) {
        alert('최고값을 넘었습니다.');
        return null;
     } else {
       data.unshift('1');
     }
   }

   return data.join(''); // , 제거하고 배열 조인.
 }

function init(str,num,is) {
   return integer2string(string2integer(str),num,is);
 }

 // 초기값 생성
var def = "000";

document.writeln(def);

 // 반복문으로 테스트
for(var i = 0; i < 1000; i++) {
   def = init(def,1,false);
   document.writeln(def);
 }

결과 : 000 001 002 003 004 005 007 008 009 00a 00b 00c 00d ................

 자바 예제 소스


String str = "0dasdweZ";
out.print(CountUtils.get(str,1,false)); // 0dasdwf0 결과


/**
 * @class CountUtils
 * @brief 숫자 , 문자열을 포함한 증가값을 생성한다.
 *
 * registered date 20101019
 * programmed by Seok Kyun. Choi. (최석균)
 * http://syaku.tistory.com
 */

package com.syaku.util;

import org.apache.commons.lang.ArrayUtils;

public class CountUtils {

  private static char number[] = {'0','1','2','3','4','5','7','8','9'};
  private static char alphabet[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  private static char ALPHABET[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
  private static char all[] = ArrayUtils.addAll(ArrayUtils.addAll(number,alphabet),ALPHABET);
  private static int total = all.length;

  /**
  * @method : string2number(parameter)
  * @brief : 인자의 문자와 일치하는 값은 순번을 반환한다.
  * @parameter : 문자열
  * @return : int[]
  */
  public static int[] string2number(String str) {
    int chr = str.length();
    char ch[] =str.toCharArray(); 

    int[] data = { };

    for (int c = (chr-1); c >= 0; c--) {
      char s = ch[c]; // 인수 문자

      for (int i = 0; i < total; i++) {
        char key = all[i];

        // 인수의 문자와 all 배열의 문자가 일치할 경우 배열에 삽입.
        if (key == s) { data = ArrayUtils.add(data,i); }
      }

    }

    return data;
  }

  /**
  * @method : number2string(parameter1,parameter2,parameter3)
  * @brief : 숫자형으로 얻은 순번배열을 parameter2 의 값만큼 더하고 순번의 문자값을 반환한다.
  * @parameters {
        parameter : int[] 숫자형 순번배열
        parameter2 : int 카운트할 숫자값.
        parameter3 : boolean - true 최고 값을 넘을 경우 예외처리함 , false 반올림처리함.
      }
  * @return : String 숫자형 순번배열의 순번 위치의 문자열을 조합하여 반환함.
  */
  public static String number2string(int[] array,int num,boolean asc) {
    int count = array.length;
    boolean is_key = false;
    char data[] = new char[count];


    for (int i = 0; i < count; i++) {

      int key = array[i];

      if (i == 0) { // 첫번째 배열에 인수의 값을 더함.
        key = key + num;
      }

      if (is_key) { // 올림수 여부
        key = key + 1;
      }
      

      if (key >= total) {
        key = key - total;
        is_key = true;
      } else {
        is_key = false;
      }

    data[(count-1) - i] = all[key]; // 역순으로 배열 생성.

    }


    if (is_key) { // 마지막 루프에서 올림수가 있을 경우 한자리 추가
      if (asc == false) {
         return null;
      } else {
        ArrayUtils.add(data,0,'1');
      }
    }

    // , 제거하고 배열 조인.
    String ret = ArrayUtils.toString(data);
    return ret.replaceAll("[{},]",""); 
  }

  /**
  * @method : get(parameter1,parameter2,parameter3)
  * @brief : 배열을 사용하여 오름 카운트를 구현함.
  * @parameters {
        parameter : 문자열
        parameter2 : int 카운트할 숫자값.
        parameter3 : boolean - true 최고 값을 넘을 경우 예외처리함 , false 반올림처리함.
      }
  * @return : String 숫자형 순번배열의 순번 위치의 문자열을 조합하여 반환함.
  */
  public static String get(String str,int num,boolean asc) {
    int data[] = string2number(str);
    return number2string(data,num,asc);
  }

}