2010-01-02 2 views
2

저는 빌드하고있는 레일즈 애플리케이션의 백엔드로 MongoDB를 사용하고 있습니다. 몽고는 기본적으로, 쉽게 샤딩 수 있도록 그 기록을 24 자 진수 ID를 생성 그래서 내 URL이처럼 보이는 바람 : 아주 예쁜하지Ruby/Rails의 16 진수 문자열 압축하기

example.com/companies/4b3fc1400de0690bf2000001/employees/4b3ea6e30de0691552000001 

. Rails URL 규칙을 고수하고 싶지만이 ID는 데이터베이스에 그대로 두십시오. 나는 행복 타협 이상의 문자를 사용하여 짧은 컬렉션 이러한 진수 ID를 압축하는 것입니다 생각, 그래서 그들은 같은 것을 볼 것입니다 : 내가 압축을 반대 것 내 컨트롤러에 다음

example.com/companies/3ewqkvr5nj/employees/9srbsjlb2r 

를 원래의 진수 ID를 얻을 그것을 사용하여 레코드를 찾습니다.

제 질문은 이러한 ID를 앞뒤로 변환하는 가장 좋은 방법은 무엇입니까? 나는 물론 그들이 가능한 한 짧아 지길 바라지 만, 변환하기 쉽고 안전하며 간단하다.

감사합니다.

답변

5

당신은 그것의 문자열 표현을 짧게 만들 수 16보다 높은베이스에 16 진수 ID를 나타낼 수의 기준이 16 진수 값으로 변환합니다. Ruby는 2부터 36까지 기본 작업을 지원합니다.

b36 = '4b3fc1400de0690bf2000001'.hex.to_s(36) 
# => "29a6dblglcujcoeboqp" 

는이 같은 뭔가를 할 수 다시 24 문자열로 변환 :

'%024x' % b36.to_i(36) 
# => "4b3fc1400de0690bf2000001" 

더 나은 "압축"을 달성하기 위해 당신이 36보다 높은 자료의 ID를 나타낼 수 있습니다. Ruby 라이브러리가 도움이 될 것입니다. all-your-base 보석은 그러한 라이브러리 중 하나입니다.

0-9, a-zA-Z 문자 만 사용하므로 기본적으로 URL 안전성을 나타 내기 때문에 62 표현을 사용하는 것이 좋습니다. 심지어 당신은 여전히 ​​다루기 16 문자 식별자로 끝날베이스 (62) 대표와

0

base64를 사용하면 더 짧게 만들 수 있습니다. '+'및 '/'대신 '-'및 '_'을 사용하고 있는지 확인하십시오. 패딩 =을자를 수도 있습니다.

코드 64

def MD5hex2base64(str) 
    h1=[].clear 

    # split the 32 byte hex into a 16 byte array 
    16.times{ h1.push(str.slice!(0,2).hex) } 
    # pack (C* = unsigned char), (m = base64 encoded output) 
    [h1.pack("C*")].pack("m") 
end 
+0

어떻게하면됩니까? 문자열 ID에 Base64.encode64를 사용하여 시도했지만 그만큼 길어집니다. – PreciousBodilyFluids

+0

이 스 니펫은 어떻게 수행 할 수 있는지 보여줍니다. http://rubyforge.org/snippet/detail.php?type=snippet&id=33 –

+2

Base64.encode64는 이진 데이터 대신 문자열로 사용하기 때문에 ID를 더 길게 만듭니다. – epochwolf

1

:

'4b3fc1400de0690bf2000001'.hex.to_base_62 
# => "UHpdfMzq7jKLcvyr" 

피하는 레일 규칙 약간 다른 타협의베이스 32 표현은 "URL ID가"로 사용하는 것입니다 created_at 개체의 날짜입니다.

aCompany.created_at 
# => Sat Aug 13 20:05:35 -0500 2011 
aCompany.created_at.to_i.to_s(32) 
# => "174e7qv" 

당신은 특수 목적 속성을 추적 할 필요없이 매우 짧은 식별자 (7 자)를 얻을이 방법 (MongoMapper에, 그것은 자동 created_atupdated_at 특성을 얻을 수있는 모델 timestamps!를 추가하는 간단한 문제입니다) .