2012-06-08 25 views
5

Czy istnieje jakiś sposób, aby wygenerować kolor z dowolnego ciągu znaków w Java/Android niczym funkcji/Hash Szyfrowanie?Android/Java: Konwersja dowolny ciąg do koloru (hex)

Przykład: ciąg "Home" generuje kolor jak "# FF1234".
String "Sky" generuje kolor jak "# 00CC33" ...

bez randomizacji. Tak, system będzie zawsze obliczyć te same kolory, które struny

Dzięki

EDIT: Struny są dowolnie definiowane przez użytkownika

+0

Można zdefiniować HashMap prawdopodobnie gdzieś, że mapuje struny do kolorów, choć trzeba by wypełnić samemu. Domyślna klasa kolorów java ma już zdefiniowane domyślne kolory, ale nie jest to szalone jak "Sky".To rzeczy takie jak "Czerwony" i "LightGray" –

+1

Oczywiście, możesz zdefiniować dowolną funkcję matematyczną, która ma łączyć znaki w 24-bitową (bez alpha) lub 32-bitową (jeśli chcesz mieć wartość alfa), a następnie zastosować ją jako kolor dla słowo. Funkcja skrótu również może działać i najprawdopodobniej zapewni lepszą dyspersję kolorów w całym zakresie kolorów (w dzisiejszych komputerach). Hash jak Dowolna funkcja matematyczna, która NIE korzysta z losowego wprowadzania spowoduje, że zawsze otrzymamy ten sam kolor dla tego ciągu wejściowego. Jedyną rzeczą, na którą można spojrzeć, jest wielkość liter. – trumpetlicks

+0

@Hans - mapa HASH byłaby bardzo duża, gdyby jego wejście było dowolnym arbitralnym słowem. Lepiej obliczyć hasz i zastosować dowolną statyczną część (skrót będzie większy niż 32 lub 24 bity) bitów wyjściowych skrótu do wartości koloru. Mogłem zobaczyć potencjalnie za pomocą bardziej uproszczonego CRC lub czegoś podobnego, ale odległość między wartościami nie byłaby tak dobra, jak w przypadku HASH. – trumpetlicks

Odpowiedz

8

String.hashCode() zwróci wartość int, więc to tylko kwestia toczenia, że ​​w na wartość hex.

String s = "Home"; 
String color = String.format("#%X", s.hashCode()); 
+0

Jest to ponownie uproszczona odpowiedź, jeśli przejrzysz procedurę Java hashCode dla łańcucha znaków, jest to proste wielokrotne dodawanie. Spowoduje to sytuacje, w których "Home" otrzyma ten sam kod skrótu jako "moeH". To może być w porządku, jeśli jego wymagania są takie same. – trumpetlicks

+0

Właściwie ciąg 'hashCode()' '' '' '' '' jest hashem bardziej wydajnym niż to. Te same znaki w rzeczywistości nie generują tego samego kodu. Sprawdź sam ... po prostu wykonaj 'println' na' "Home" .hashCode() 'i' "emoH" .hashCode() '... będą różne. – stuckless

+0

Ach tak, jest to spowodowane tym, że w podsumowaniu włączono i do wykładnika równania SUM (i = 0, i trumpetlicks

1

Domyślam się, że nie próbują zmienić plik zasobów.

Zależy jak chcesz to zrobić, aby być uczciwym. Są miliony sposobów, aby osiągnąć to

Dla mnie wziąłbym wartość ASCII każdego znaku, należy dodać je wszystkie, a następnie przekształcić go hex. Z powiedział, że na pokrycie przypadku zbyt wielu znaków, to mod go do max wielkości ciąg szesnastkowy. TO ZNACZY. FFFFFF, więc w ten sposób otacza się i zaczyna od nowa.

//pseudocode 
counter = 0; 
foreach(char in string){ 
    counter+=(int)char; 

} 
counter = convertToHex(counter)%0xffffff; 
string x = "#"+counter.toString(); 

po to by przechowywać je w ciąg

string x = "#"+hexVal.toString(); 

je można z nim zrobić, co chciał.

+0

Może to być zbyt uproszczone, jeśli próbuje uzyskać lepsze dopasowanie tekstu do koloru w stosunku jeden-do-jednego. Prosty dodatek może być łatwiejszy w wielu słowach o tym samym kolorze. Z drugiej strony jest to świetny przykład bardzo uproszczonej procedury matematycznej, o czym pisałem w powyższej notatce. – trumpetlicks

+0

, więc chciałby mieć słownik słów i skojarzone z nimi kolory, które bym pomyślał, choć nadal by się powtarzał, gdyby było wystarczająco dużo słów na stronie – Fallenreaper

+0

@ Fallenreaper - To naprawdę zależy od tego, co próbuje zrobić. Jeśli próbuje dotrzeć tak blisko, jak to tylko możliwe, do mapowania 1 do 1, wtedy HASH byłby prawdopodobnie NAJBLIŻSZĄ odpowiedzią, ponieważ HASH nie tylko uwzględniałby wartość każdej litery, ale także porządek (co mapowanie 1-do-1). Jeśli odwzorowuje dowolne słowo, słownik może uzyskać zbyt dużą ilość. Calc na żywo będzie do zrobienia. Nawet HASH ma swoje problemy, gdy są stosowane tutaj, ponieważ tylko 24 do 32 bitów (znacznie większy) hash zostanie użyty. Z nieskończoną ilością słów, powtórzenia będą musiały się zdarzyć. – trumpetlicks

0

Można spróbować czegoś takiego:

String s = "Home"; 
byte[] b = s.getBytes("US-ASCII"); 
StringBuffer hexString = new StringBuffer(); 
for (int i=0;i<b.length;i++) { 
    hexString.append(Integer.toHexString(0xFF & b[i])); 
    } 
String finalHex = "#" + hexString.substring(0,6); 
System.out.println(finalHex); 

generuje hex: #486f6d

Podobnie generować hex dla wszystkich String s chcesz i dodajemy je do HashMap jako parę klucz-wartość .

+0

To zajmuje się zamawianiem, ale tak naprawdę będzie obliczane tylko wtedy, gdy słowo będzie takie samo lub różne dla pierwszych 6 znaków. W tym przypadku "homer123456" otrzyma ten sam kolor co "homer178902". – trumpetlicks

+0

Ups. Tak, jasne. Ale jeśli nie zrobię podciągu, heks nie stanie się poprawnym hexem kolorów, to po prostu przekroczy prawidłową długość. –

+1

dla każdej iteracji w pętli, wszystko co robisz to dołączanie funkcji matematycznej w oparciu o aktualną postać. Oznacza to, że zasadniczo tworzysz kolejny ciąg o tym samym rozmiarze co s (który umieściłeś w b). Następnie po prostu bierzesz podciąg z pierwszych 6 znaków ciągu, który wygenerowałeś. Stworzyłeś mapowanie 1-do-1 opartego na postaci i pozostawiasz za sobą całą postać, którą wygenerowałeś poprzedni znak 6). – trumpetlicks

3

Spróbuj poszukać tutaj, jak utworzyć skrót wiadomości na twój ciąg.

http://www.mkyong.com/java/java-sha-hashing-example/

Po utworzeniu skrótu wiadomości, użyj ile każdy z bajtów generowana, aby utworzyć wartość koloru. Możesz użyć najmniej znaczącego, najbardziej znaczącego, w dowolnym miejscu w środku.

+0

Ten sam problem, który wskazałeś w mojej odpowiedzi, nie sądzisz? Przepraszam na wszelki wypadek, ponieważ czuję, że mogę się mylić. –

+0

Zrozumiałeś swój punkt, dzięki komentarzowi do mojego posta. :-) –

+0

Szkoda, że ​​nie mogłem przegłosować, ale dzisiaj kończę głosami. –

3

Dzięki konsekwentnej krycie:

String opacity = "#99"; //opacity between 00-ff 
String hexColor = String.format(
     opacity + "%06X", (0xFFFFFF & anyString.hashCode())); 

lub przy użyciu nowego projektu materiał android Paleta:
https://gist.github.com/odedhb/79d9ea471c10c040245e